Anchor 插件
Alpine 的 Anchor 插件允许你轻松地将一个元素的位置锚定到页面上的另一个元素。
这个功能在创建下拉菜单、弹出框、对话框和使用 Alpine 的提示框时非常有用。
该插件使用的"锚定"功能由 Floating UI 项目提供。
安装
你可以通过 <script> 标签引入或通过 NPM 安装来使用此插件:
通过 CDN
你可以将此插件的 CDN 构建版本作为 <script> 标签引入,只需确保在 Alpine 核心 JS 文件之前引入。
<!-- Alpine 插件 -->
<script defer src="https://cdn.jsdelivr.net/npm/@alpinejs/[email protected]/dist/cdn.min.js"></script>
<!-- Alpine 核心 -->
<script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/cdn.min.js"></script>
通过 NPM
你可以从 NPM 安装 Anchor 以在打包中使用:
npm install @alpinejs/anchor
然后从你的打包工具中初始化它:
import Alpine from 'alpinejs'
import anchor from '@alpinejs/anchor'
Alpine.plugin(anchor)
...
x-anchor
使用此插件的主要 API 是 x-anchor 指令。
要使用此插件,将 x-anchor 指令添加到任何元素,并传入要锚定位置的元素的引用(通常是页面上的一个按钮)。
默认情况下,x-anchor 会将元素的 CSS 设置为 position: absolute 以及适当的 top 和 left 值。如果被锚定的元素通常显示在参考元素下方但没有足够空间,它的样式将被调整以显示在元素上方。
例如,这里有一个简单的下拉菜单,锚定到切换它的按钮:
<div x-data="{ open: false }">
<button x-ref="button" @click="open = ! open">Toggle</button>
<div x-show="open" x-anchor="$refs.button">
Dropdown content
</div>
</div>
定位
x-anchor 允许你使用以下修饰符自定义锚定元素的定位:
- 底部:
.bottom、.bottom-start、.bottom-end - 顶部:
.top、.top-start、.top-end - 左侧:
.left、.left-start、.left-end - 右侧:
.right、.right-start、.right-end
以下是一个使用 .bottom-start 将下拉菜单定位在参考元素下方并靠右对齐的示例:
<div x-data="{ open: false }">
<button x-ref="button" @click="open = ! open">Toggle</button>
<div x-show="open" x-anchor.bottom-start="$refs.button">
Dropdown content
</div>
</div>
固定定位
默认情况下,x-anchor 对锚定元素应用 position: absolute。这在大多数情况下没问题,但当参考元素位于带有 overflow: hidden、overflow: clip 或 overflow: auto 的容器内时,锚定元素会随之被裁剪。
你可以通过添加 .fixed 修饰符来指示 Floating UI 改用固定定位策略:
<div x-data="{ open: false }">
<button x-ref="button" @click="open = ! open">Toggle</button>
<div x-show="open" x-anchor.fixed="$refs.button">
Dropdown content
</div>
</div>
注意: 任何祖先元素上的
transform、filter、perspective、backdrop-filter、will-change或contain都会为position: fixed后代元素创建一个新的包含块(根据 CSS 规范)。发生这种情况时,.fixed将相对于该祖先元素表现为position: absolute,并且无法逃脱其overflow: hidden。如果.fixed似乎不起作用,请检查是否有应用了 transform 的祖先元素。
偏移量
你可以使用 .offset.[px 值] 修饰符为锚定元素添加偏移量,如下所示:
<div x-data="{ open: false }">
<button x-ref="button" @click="open = ! open">Toggle</button>
<div x-show="open" x-anchor.offset.10="$refs.button">
Dropdown content
</div>
</div>
防止翻转位置
默认情况下,如果锚定元素在参考元素下方没有足够的空间渲染,x-anchor 会翻转其位置。
你可以通过添加 .noflip 修饰符来阻止此行为:
<div x-data="{ open: false }">
<button x-ref="button" @click="open = ! open">Toggle</button>
<div x-show="open" x-anchor.noflip="$refs.button">
Dropdown content
</div>
</div>
手动样式
默认情况下,x-anchor 会在内部将定位样式应用到你的元素。如果你更希望完全控制样式,可以传递 .no-style 修饰符,并使用 $anchor 魔法在另一个 Alpine 表达式中访问这些值。
以下是一个绕过 x-anchor 内部样式,转而使用 x-bind:style 自行应用样式的示例:
<div x-data="{ open: false }">
<button x-ref="button" @click="open = ! open">Toggle</button>
<div
x-show="open"
x-anchor.no-style="$refs.button"
x-bind:style="{ position: 'absolute', top: $anchor.y+'px', left: $anchor.x+'px' }"
>
Dropdown content
</div>
</div>
结合
.no-style与.fixed: 当你选择不使用 Alpine 的内部样式并希望使用固定定位时,记得自己设置position: 'fixed'。$anchor.x和$anchor.y根据当前激活的策略返回坐标空间中的值——绝对坐标相对于偏移父元素,固定坐标相对于视口——因此应用错误的position会使元素显示在错误的位置。<div x-show="open" x-anchor.no-style.fixed="$refs.button" x-bind:style="{ position: 'fixed', top: $anchor.y+'px', left: $anchor.x+'px' }" > Dropdown content </div>
锚定到 ID
到目前为止的示例都是使用 Alpine refs 锚定到其他元素。
因为 x-anchor 接受任何 DOM 元素的引用,你可以使用像 document.getElementById() 这样的工具来通过其 id 属性锚定到一个元素:
<div x-data="{ open: false }">
<button id="trigger" @click="open = ! open">Toggle</button>
<div x-show="open" x-anchor="document.getElementById('trigger')">
Dropdown content
</div>
</div>