Tether 示例合集精读:9 个官方 Demo 的配置写法与底层源码对照
前端UI组件【免费下载链接】tetherA positioning engine to make overlays, tooltips and dropdowns better项目地址https://gitcode.com/gh_mirrors/te/tether点击查看免费下载Tether 官方文档的 Examples 章节以“示例目录”的形式给出了从入门到进阶共 9 个可直接运行的定位场景examples/目录。本文逐个拆解这些示例的完整配置——包括attachment、targetAttachment、constraints、targetModifier等参数的真实取值——并对照 src/js/tether.js 与 src/js/constraint.js 的源码解释每种定位策略越界隐藏、贴边钉住、可见区对齐、滚动条跟随、链式元素是如何实现的。读完后你可以按图索骥地复现每个 Demo并理解其背后的调用链。示例总览目录结构与运行前提官方文档 docs/2-Examples/1-list_of_examples.md 将示例分为 Beginner 与 Advanced 两级页面版导航 examples/index.html 与其内容一一对应级别示例解决的问题Beginnerexamples/simple最基础的双元素定位入门Beginnerexamples/out-of-bounds元素将要超出屏幕时将其隐藏Beginnerexamples/pin将元素钉在可视区内永不越出Beginnerexamples/enable-disable用 JavaScript 动态启用/禁用 TetherAdvancedexamples/content-visible用visible修饰器对齐到另一元素的可见部分Advancedexamples/dolls数十个元素链式 tether 的性能演示Advancedexamples/element-scroll用scroll-handle修饰器跟随元素滚动条Advancedexamples/scroll用scroll-handle修饰器跟随页面滚动条Advancedexamples/viewport将元素对齐到视口中央所有示例共享两个前提需要先构建产物每个示例的index.html都引用../../dist/js/tether.js该文件由 rollup.config.js 打包生成。根据 package.json 的 scriptspnpm build内部为pnpm clean rollup -c会产出dist/pnpm start则以 watch 模式持续构建需要静态服务器示例页面是纯静态 HTML。仓库的 Cypress 流程test:cy:ci会用http-server -p 9002启动start-test-server本地运行示例时同样需要任意静态服务器示例本身不依赖构建工具运行。Beginner 示例simple最小可用的双元素定位simple/index.html 是官方推荐的起点页面包含两个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配置要点element/target接受 CSS 选择符字符串。在 src/js/tether.js 的setOptions中字符串会被document.querySelector解析为真实元素jQuery 对象则取[0]解包attachment: top left表示锚定元素自身的左上角targetAttachment: top right表示锚到目标的右上角即气泡贴在目标右侧constraints: [{ to: window, attachment: together }]约束两个元素必须保持在窗口内页面提示“Resize the page to see the Tether flip”——缩小窗口时 Tether 会自动翻转flip锚点方向这正是targetAttachment默认值auto auto参与的结果默认值见 src/js/tether.js 中的defaultsoffset: 0 0、targetOffset: 0 0、targetAttachment: auto auto、classPrefix: tether。该示例由 test/cypress/integration/simple.cy.js 的端到端测试持续验证。out-of-bounds越界即隐藏out-of-bounds/index.html 与 simple 几乎相同多了两段关键代码.tether-element.tether-out-of-bounds { display: none; }tether.on(update, function(event) { console.log(event); });原理在 src/js/constraint.js 中约束模块计算元素是否越界_calculateOOBAndPinnedLeft/_calculateOOBAndPinnedTop见 constraint.js越界时给元素添加tether-out-of-bounds类由classPrefix默认tether与out-of-bounds组合见 constraint.js示例中的 CSS 利用这个类把元素直接display: none。配合tether.on(update, ...)事件回调Tether 每次重定位都会触发你可以在应用层做更精细的处理例如淡出或重新锚定。pin把元素钉在可视区内pin/index.html 只改了约束的一项配置constraints: [{ to: window, pin: true }]pin的取值在 constraint.js 中解析传入字符串如left会按逗号拆分为数组传入true则等价于[top, left, right, bottom]即四个方向全部钉住。被钉住的每条边会额外生成pinned-top/pinned-left等类名constraint.js供 CSS 做进一步样式区分同时元素位置被钳制在约束边界内表现为“缩放窗口时元素贴着屏幕边缘移动而永不消失”。enable-disable运行时开关enable-disable/index.html 演示了 Tether 实例的两个生命周期方法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(); });点击绿色 target 即在启用/禁用之间切换。从源码看src/js/tether.jsenable()会给元素与目标添加tether-enabled类同样由classPrefix组合而来并调用position()执行定位disable()则移除该类实例的enabled标志随之翻转供业务代码做状态判断。这个“CSS 类 实例标志”的双重状态设计使 enable/disable 既能驱动样式又能驱动逻辑。Advanced 示例content-visible对齐到另一元素的“可见部分”content-visible/index.html 构造了一个 600vh 高的蓝色长条.content-box其中有一个 200px 高的黄色.element核心配置是new Tether({ element: .element, target: .content-box, attachment: middle center, targetAttachment: middle center, targetModifier: visible });targetModifier: visible是整个示例的关键。在 src/js/tether.js 的getTargetBounds中当targetModifier visible时目标边界不再取元素的完整 bounds而是取getVisibleBounds(bodyElement, target)——即目标元素与视口重叠的“可见部分”的边界。于是.element会始终对齐到.content-box当前露在屏幕内那一段的中央滚动页面时对话框跟着“可见中段”移动。实现细节可见区裁剪算法位于 src/js/utils/bounds.js。viewport把元素固定在视口中央viewport/index.html 是visible修饰器的第二种用法——目标直接取document.bodynew Tether({ element: .element, target: document.body, attachment: middle center, targetAttachment: middle center, targetModifier: visible });body的可见部分恰好就是当前视口因此.element永远停留在视口正中页面滚动示例动态生成了 300 个彩色块制造可滚动内容也不影响它。页面提示可检查元素最终计算样式Tether 在此场景下会决定使用position: fixed来维持位置。源码中还有一个等价捷径src/js/tether.js 里直接把target写成字符串viewport时会自动改写为document.bodytargetModifier: visible与示例的显式写法完全等效。scroll跟随页面滚动条scroll/index.html 在一整页约瑟夫·康拉德的小说正文上把一个提示条 tether 到页面滚动进度new Tether({ element: .pointer, attachment: middle right, targetAttachment: middle left, targetModifier: scroll-handle, target: document.body });当targetModifier scroll-handle时getTargetBounds返回getScrollHandleBoundssrc/js/tether.js即目标滚动条“拇指”thumb的几何位置。于是.pointer在垂直方向上始终与页面滚动拇指同步随滚动上下移动示例再叠加一段自定义脚本把当前章节标题与滚动百分比pageYOffset / (scrollHeight - innerHeight)写进提示条。注意 src/js/tether.js 中的配套逻辑scroll-handle修饰器会把scrollParents直接锁定为[this.target]而普通场景则用getScrollParents(target)收集滚动父级两者决定了滚动监听的注册对象。element-scroll跟随“元素内部”的滚动条element-scroll/index.html 把同样的思路搬到容器级滚动上页面中有一个position: fixed、overflow-y: scroll的 80vh 阅读框.scroll并刻意用::-webkit-scrollbar { display: none }隐藏原生滚动条配置为new Tether({ element: pointer, // .pointer target: scroll, // .scroll attachment: middle right, targetAttachment: middle left, targetModifier: scroll-handle });与 scroll 示例的差异在于target是任意元素而非 bodyTether 会为它计算一个替代滚动条.pointer3.6em 高、与容器等宽垂直位置严格映射该容器scrollTop / (scrollHeight - clientHeight)的进度。示例后续代码高亮当前句只是演示性效果与 Tether 无关。这展示了scroll-handle修饰器可以驱动“自定义滚动条、阅读进度条、章节导航”一类组件。dolls60 个元素的链式性能演示dolls/index.html 配合 examples/dolls/dolls.js 是一个压力/性能演示脚本创建 60 个div追加进.scroll容器每个元素 tether 到前一个元素形成一条链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 个元素左右折返一次dir在 left/right 间切换targetOffset给出 10px 的间隙。演示的交互是“拖动左上角第一个元素”dolls.js中监听mousedown/mousemove更新被拖元素的top/left随后调用静态方法Tether.position()一次性重算全部实例——这是链式布局的关键否则只有第一个 Tether 更新而其余 59 个滞后。这个示例直观验证了 Tether 批量实例下的重定位行为。示例的自动化验证文档目录中未列出、但对“示例可长期运行”至关重要的一点这些示例有专门的端到端测试。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形成闭环——也就是说每个 Demo 的行为变更都会被回归测试捕获。本地想打开示例时流程为pnpm build生成dist/再在仓库根目录起任意静态服务器访问examples/示例名/index.html。小结从示例到配置的选择路径综合这 9 个 Demo可以把 Tether 的定位能力归纳为一张“场景 → 参数”速查表场景关键参数基础气泡/工具提示attachmenttargetAttachmentconstraints: [{ to: window, attachment: together }]放不下就隐藏同上约束靠默认类tether-out-of-bounds控制显示永不越出窗口约束中加pin: true等价四边钉住动态开关实例方法tether.enable()/tether.disable()tether.enabled标志对齐可见区targetModifier: visible或target: viewport简写跟随滚动条/进度targetModifier: scroll-handletarget 可为 body 或任意可滚动元素文档结尾也明确欢迎社区贡献新示例“please send a PR with any examples you might create”。结合上表与 examples/ 下每个目录“一个 index.html 自包含”的组织方式扩展一个新 Demo 的成本很低新建目录、写一个引用../../dist/js/tether.js的页面需要时再补一个 Cypress 用例即可。赞分享前端UI组件【免费下载链接】tetherA positioning engine to make overlays, tooltips and dropdowns better项目地址https://gitcode.com/gh_mirrors/te/tether点击查看免费下载相关推荐Zustand 官方 Starter 示例解读从零搭建计数 Demo 并剖析 create 的底层实现Zustand 官方 Starter 示例解读从零搭建计数 Demo 并剖析 create 的底层实现 Zustand是一个轻量级的 React 状态前端CPython email 包实战官方 7 个示例逐行精讲读写、发送与解析邮件CPython email 包实战官方 7 个示例逐行精讲读写、发送与解析邮件 本文以 CPython 官方文档 Doc/library/email.ex编程语言语言运行时解释器标准库KubeSphere 配置解码底层库解析mapstructure v1.5.0 变更日志与源码实现对照KubeSphere 配置解码底层库解析mapstructure v1.5.0 变更日志与源码实现对照 本文以 KubeSphere 仓库 vendor 目录前端UI组件设计系统上一篇Windows 11终极优化指南使用Win11Debloat一键提升70%系统性能下一篇NoteDiscovery企业级部署指南5分钟实现智能知识库容器化配置创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考