官方 Demo 的配置寫法與底層源碼對(duì)照)
前端UI組件【免費(fèi)下載鏈接】tetherA positioning engine to make overlays, tooltips and dropdowns better項(xiàng)目地址https://gitcode.com/gh_mirrors/te/tether點(diǎn)擊查看免費(fèi)下載Tether 官方文檔的 Examples 章節(jié)以“示例目錄”的形式給出了從入門到進(jìn)階共 9 個(gè)可直接運(yùn)行的定位場(chǎng)景examples/目錄。本文逐個(gè)拆解這些示例的完整配置——包括attachment、targetAttachment、constraints、targetModifier等參數(shù)的真實(shí)取值——并對(duì)照 src/js/tether.js 與 src/js/constraint.js 的源碼解釋每種定位策略越界隱藏、貼邊釘住、可見區(qū)對(duì)齊、滾動(dòng)條跟隨、鏈?zhǔn)皆厥侨绾螌?shí)現(xiàn)的。讀完后你可以按圖索驥地復(fù)現(xiàn)每個(gè) Demo并理解其背后的調(diào)用鏈。示例總覽目錄結(jié)構(gòu)與運(yùn)行前提官方文檔 docs/2-Examples/1-list_of_examples.md 將示例分為 Beginner 與 Advanced 兩級(jí)頁面版導(dǎo)航 examples/index.html 與其內(nèi)容一一對(duì)應(yīng)級(jí)別示例解決的問題Beginnerexamples/simple最基礎(chǔ)的雙元素定位入門Beginnerexamples/out-of-bounds元素將要超出屏幕時(shí)將其隱藏Beginnerexamples/pin將元素釘在可視區(qū)內(nèi)永不越出Beginnerexamples/enable-disable用 JavaScript 動(dòng)態(tài)啟用/禁用 TetherAdvancedexamples/content-visible用visible修飾器對(duì)齊到另一元素的可見部分Advancedexamples/dolls數(shù)十個(gè)元素鏈?zhǔn)?tether 的性能演示Advancedexamples/element-scroll用scroll-handle修飾器跟隨元素滾動(dòng)條Advancedexamples/scroll用scroll-handle修飾器跟隨頁面滾動(dòng)條Advancedexamples/viewport將元素對(duì)齊到視口中央所有示例共享兩個(gè)前提需要先構(gòu)建產(chǎn)物每個(gè)示例的index.html都引用../../dist/js/tether.js該文件由 rollup.config.js 打包生成。根據(jù) package.json 的 scriptspnpm build內(nèi)部為pnpm clean rollup -c會(huì)產(chǎn)出dist/pnpm start則以 watch 模式持續(xù)構(gòu)建需要靜態(tài)服務(wù)器示例頁面是純靜態(tài) HTML。倉庫的 Cypress 流程test:cy:ci會(huì)用http-server -p 9002啟動(dòng)start-test-server本地運(yùn)行示例時(shí)同樣需要任意靜態(tài)服務(wù)器示例本身不依賴構(gòu)建工具運(yùn)行。Beginner 示例simple最小可用的雙元素定位simple/index.html 是官方推薦的起點(diǎn)頁面包含兩個(gè)div.element與.target和一段 10 行左右的腳本div classelement/div div classtarget/div script src../../dist/js/tether.js/script script new Tether({ element: .element, target: .target, attachment: top left, targetAttachment: top right, constraints: [{ to: window, attachment: together }] }); /script配置要點(diǎn)element/target接受 CSS 選擇符字符串。在 src/js/tether.js 的setOptions中字符串會(huì)被document.querySelector解析為真實(shí)元素jQuery 對(duì)象則取[0]解包attachment: top left表示錨定元素自身的左上角targetAttachment: top right表示錨到目標(biāo)的右上角即氣泡貼在目標(biāo)右側(cè)constraints: [{ to: window, attachment: together }]約束兩個(gè)元素必須保持在窗口內(nèi)頁面提示“Resize the page to see the Tether flip”——縮小窗口時(shí) Tether 會(huì)自動(dòng)翻轉(zhuǎn)flip錨點(diǎn)方向這正是targetAttachment默認(rèn)值auto auto參與的結(jié)果默認(rèn)值見 src/js/tether.js 中的defaultsoffset: 0 0、targetOffset: 0 0、targetAttachment: auto auto、classPrefix: tether。該示例由 test/cypress/integration/simple.cy.js 的端到端測(cè)試持續(xù)驗(yàn)證。out-of-bounds越界即隱藏out-of-bounds/index.html 與 simple 幾乎相同多了兩段關(guān)鍵代碼.tether-element.tether-out-of-bounds { display: none; }tether.on(update, function(event) { console.log(event); });原理在 src/js/constraint.js 中約束模塊計(jì)算元素是否越界_calculateOOBAndPinnedLeft/_calculateOOBAndPinnedTop見 constraint.js越界時(shí)給元素添加tether-out-of-bounds類由classPrefix默認(rèn)tether與out-of-bounds組合見 constraint.js示例中的 CSS 利用這個(gè)類把元素直接display: none。配合tether.on(update, ...)事件回調(diào)Tether 每次重定位都會(huì)觸發(fā)你可以在應(yīng)用層做更精細(xì)的處理例如淡出或重新錨定。pin把元素釘在可視區(qū)內(nèi)pin/index.html 只改了約束的一項(xiàng)配置constraints: [{ to: window, pin: true }]pin的取值在 constraint.js 中解析傳入字符串如left會(huì)按逗號(hào)拆分為數(shù)組傳入true則等價(jià)于[top, left, right, bottom]即四個(gè)方向全部釘住。被釘住的每條邊會(huì)額外生成pinned-top/pinned-left等類名constraint.js供 CSS 做進(jìn)一步樣式區(qū)分同時(shí)元素位置被鉗制在約束邊界內(nèi)表現(xiàn)為“縮放窗口時(shí)元素貼著屏幕邊緣移動(dòng)而永不消失”。enable-disable運(yùn)行時(shí)開關(guān)enable-disable/index.html 演示了 Tether 實(shí)例的兩個(gè)生命周期方法var tether new Tether({ element: .element, target: .target, attachment: top left, targetAttachment: top right }); document.querySelector(.target).addEventListener(click, function(){ if (tether.enabled) tether.disable(); else tether.enable(); });點(diǎn)擊綠色 target 即在啟用/禁用之間切換。從源碼看src/js/tether.jsenable()會(huì)給元素與目標(biāo)添加tether-enabled類同樣由classPrefix組合而來并調(diào)用position()執(zhí)行定位disable()則移除該類實(shí)例的enabled標(biāo)志隨之翻轉(zhuǎn)供業(yè)務(wù)代碼做狀態(tài)判斷。這個(gè)“CSS 類 實(shí)例標(biāo)志”的雙重狀態(tài)設(shè)計(jì)使 enable/disable 既能驅(qū)動(dòng)樣式又能驅(qū)動(dòng)邏輯。Advanced 示例content-visible對(duì)齊到另一元素的“可見部分”content-visible/index.html 構(gòu)造了一個(gè) 600vh 高的藍(lán)色長(zhǎng)條.content-box其中有一個(gè) 200px 高的黃色.element核心配置是new Tether({ element: .element, target: .content-box, attachment: middle center, targetAttachment: middle center, targetModifier: visible });targetModifier: visible是整個(gè)示例的關(guān)鍵。在 src/js/tether.js 的getTargetBounds中當(dāng)targetModifier visible時(shí)目標(biāo)邊界不再取元素的完整 bounds而是取getVisibleBounds(bodyElement, target)——即目標(biāo)元素與視口重疊的“可見部分”的邊界。于是.element會(huì)始終對(duì)齊到.content-box當(dāng)前露在屏幕內(nèi)那一段的中央滾動(dòng)頁面時(shí)對(duì)話框跟著“可見中段”移動(dòng)。實(shí)現(xiàn)細(xì)節(jié)可見區(qū)裁剪算法位于 src/js/utils/bounds.js。viewport把元素固定在視口中央viewport/index.html 是visible修飾器的第二種用法——目標(biāo)直接取document.bodynew Tether({ element: .element, target: document.body, attachment: middle center, targetAttachment: middle center, targetModifier: visible });body的可見部分恰好就是當(dāng)前視口因此.element永遠(yuǎn)停留在視口正中頁面滾動(dòng)示例動(dòng)態(tài)生成了 300 個(gè)彩色塊制造可滾動(dòng)內(nèi)容也不影響它。頁面提示可檢查元素最終計(jì)算樣式Tether 在此場(chǎng)景下會(huì)決定使用position: fixed來維持位置。源碼中還有一個(gè)等價(jià)捷徑src/js/tether.js 里直接把target寫成字符串viewport時(shí)會(huì)自動(dòng)改寫為document.bodytargetModifier: visible與示例的顯式寫法完全等效。scroll跟隨頁面滾動(dòng)條scroll/index.html 在一整頁約瑟夫·康拉德的小說正文上把一個(gè)提示條 tether 到頁面滾動(dòng)進(jìn)度new Tether({ element: .pointer, attachment: middle right, targetAttachment: middle left, targetModifier: scroll-handle, target: document.body });當(dāng)targetModifier scroll-handle時(shí)getTargetBounds返回getScrollHandleBoundssrc/js/tether.js即目標(biāo)滾動(dòng)條“拇指”thumb的幾何位置。于是.pointer在垂直方向上始終與頁面滾動(dòng)拇指同步隨滾動(dòng)上下移動(dòng)示例再疊加一段自定義腳本把當(dāng)前章節(jié)標(biāo)題與滾動(dòng)百分比pageYOffset / (scrollHeight - innerHeight)寫進(jìn)提示條。注意 src/js/tether.js 中的配套邏輯scroll-handle修飾器會(huì)把scrollParents直接鎖定為[this.target]而普通場(chǎng)景則用getScrollParents(target)收集滾動(dòng)父級(jí)兩者決定了滾動(dòng)監(jiān)聽的注冊(cè)對(duì)象。element-scroll跟隨“元素內(nèi)部”的滾動(dòng)條element-scroll/index.html 把同樣的思路搬到容器級(jí)滾動(dòng)上頁面中有一個(gè)position: fixed、overflow-y: scroll的 80vh 閱讀框.scroll并刻意用::-webkit-scrollbar { display: none }隱藏原生滾動(dòng)條配置為new Tether({ element: pointer, // .pointer target: scroll, // .scroll attachment: middle right, targetAttachment: middle left, targetModifier: scroll-handle });與 scroll 示例的差異在于target是任意元素而非 bodyTether 會(huì)為它計(jì)算一個(gè)替代滾動(dòng)條.pointer3.6em 高、與容器等寬垂直位置嚴(yán)格映射該容器scrollTop / (scrollHeight - clientHeight)的進(jìn)度。示例后續(xù)代碼高亮當(dāng)前句只是演示性效果與 Tether 無關(guān)。這展示了scroll-handle修飾器可以驅(qū)動(dòng)“自定義滾動(dòng)條、閱讀進(jìn)度條、章節(jié)導(dǎo)航”一類組件。dolls60 個(gè)元素的鏈?zhǔn)叫阅苎菔綿olls/index.html 配合 examples/dolls/dolls.js 是一個(gè)壓力/性能演示腳本創(chuàng)建 60 個(gè)div追加進(jìn).scroll容器每個(gè)元素 tether 到前一個(gè)元素形成一條鏈var count 60; var parent null; var dir left; while (count--){ var el document.createElement(div); el.setAttribute(data-index, count); document.querySelector(.scroll).appendChild(el); if (count % 10 0) dir dir right ? left : right; if (parent){ tethers.push(new Tether({ element: el, target: parent, attachment: middle dir, targetOffset: (dir left ? 10px 10px : 10px -10px) })); } parent el; }可以看到鏈的走向每 10 個(gè)元素左右折返一次dir在 left/right 間切換targetOffset給出 10px 的間隙。演示的交互是“拖動(dòng)左上角第一個(gè)元素”dolls.js中監(jiān)聽mousedown/mousemove更新被拖元素的top/left隨后調(diào)用靜態(tài)方法Tether.position()一次性重算全部實(shí)例——這是鏈?zhǔn)讲季值年P(guān)鍵否則只有第一個(gè) Tether 更新而其余 59 個(gè)滯后。這個(gè)示例直觀驗(yàn)證了 Tether 批量實(shí)例下的重定位行為。示例的自動(dòng)化驗(yàn)證文檔目錄中未列出、但對(duì)“示例可長(zhǎng)期運(yùn)行”至關(guān)重要的一點(diǎn)這些示例有專門的端到端測(cè)試。test/cypress/integration/ 下存在simple.cy.js、enable-disable.cy.js、pin.cy.js、scroll.cy.js、content-visible.cy.js、testbed.cy.js等用例配合package.json中的test:cy:ci先pnpm build再起http-server -p 9002最后cypress run形成閉環(huán)——也就是說每個(gè) Demo 的行為變更都會(huì)被回歸測(cè)試捕獲。本地想打開示例時(shí)流程為pnpm build生成dist/再在倉庫根目錄起任意靜態(tài)服務(wù)器訪問examples/示例名/index.html。小結(jié)從示例到配置的選擇路徑綜合這 9 個(gè) Demo可以把 Tether 的定位能力歸納為一張“場(chǎng)景 → 參數(shù)”速查表場(chǎng)景關(guān)鍵參數(shù)基礎(chǔ)氣泡/工具提示attachmenttargetAttachmentconstraints: [{ to: window, attachment: together }]放不下就隱藏同上約束靠默認(rèn)類tether-out-of-bounds控制顯示永不越出窗口約束中加pin: true等價(jià)四邊釘住動(dòng)態(tài)開關(guān)實(shí)例方法tether.enable()/tether.disable()tether.enabled標(biāo)志對(duì)齊可見區(qū)targetModifier: visible或target: viewport簡(jiǎn)寫跟隨滾動(dòng)條/進(jìn)度targetModifier: scroll-handletarget 可為 body 或任意可滾動(dòng)元素文檔結(jié)尾也明確歡迎社區(qū)貢獻(xiàn)新示例“please send a PR with any examples you might create”。結(jié)合上表與 examples/ 下每個(gè)目錄“一個(gè) index.html 自包含”的組織方式擴(kuò)展一個(gè)新 Demo 的成本很低新建目錄、寫一個(gè)引用../../dist/js/tether.js的頁面需要時(shí)再補(bǔ)一個(gè) Cypress 用例即可。贊分享前端UI組件【免費(fèi)下載鏈接】tetherA positioning engine to make overlays, tooltips and dropdowns better項(xiàng)目地址https://gitcode.com/gh_mirrors/te/tether點(diǎn)擊查看免費(fèi)下載相關(guān)推薦Zustand 官方 Starter 示例解讀從零搭建計(jì)數(shù) Demo 并剖析 create 的底層實(shí)現(xiàn)Zustand 官方 Starter 示例解讀從零搭建計(jì)數(shù) Demo 并剖析 create 的底層實(shí)現(xiàn) Zustand是一個(gè)輕量級(jí)的 React 狀態(tài)前端CPython email 包實(shí)戰(zhàn)官方 7 個(gè)示例逐行精講讀寫、發(fā)送與解析郵件CPython email 包實(shí)戰(zhàn)官方 7 個(gè)示例逐行精講讀寫、發(fā)送與解析郵件 本文以 CPython 官方文檔 Doc/library/email.ex編程語言語言運(yùn)行時(shí)解釋器標(biāo)準(zhǔn)庫KubeSphere 配置解碼底層庫解析mapstructure v1.5.0 變更日志與源碼實(shí)現(xiàn)對(duì)照KubeSphere 配置解碼底層庫解析mapstructure v1.5.0 變更日志與源碼實(shí)現(xiàn)對(duì)照 本文以 KubeSphere 倉庫 vendor 目錄前端UI組件設(shè)計(jì)系統(tǒng)上一篇Windows 11終極優(yōu)化指南使用Win11Debloat一鍵提升70%系統(tǒng)性能下一篇NoteDiscovery企業(yè)級(jí)部署指南5分鐘實(shí)現(xiàn)智能知識(shí)庫容器化配置創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考