Skip to content

wire:intersect

Livewire 的 wire:intersect 指令允许你在元素进入或离开视口时执行操作。这对于延迟加载内容、触发分析或创建基于滚动的交互很有用。

基本用法

最简单的形式是在元素变为可见时运行操作:

blade
<div wire:intersect="loadMore">
    <!-- 当滚动到视图中时加载内容 -->
</div>

当元素进入视口时,将在你的组件上调用 loadMore 操作。

进入和离开事件

你可以指定是在进入、离开还是两者时运行操作:

blade
<!-- 进入视口时运行(默认) -->
<div wire:intersect="trackView">...</div>

<!-- 进入视口时运行(显式) -->
<div wire:intersect:enter="trackView">...</div>

<!-- 离开视口时运行 -->
<div wire:intersect:leave="pauseVideo">...</div>

可见性修饰符

控制在触发之前元素需要可见多少:

blade
<!-- 任何部分可见时触发(默认) -->
<div wire:intersect="load">...</div>

<!-- 一半可见时触发 -->
<div wire:intersect.half="load">...</div>

<!-- 完全可见时触发 -->
<div wire:intersect.full="load">...</div>

<!-- 自定义阈值触发(0-100) -->
<div wire:intersect.threshold.25="load">...</div>

边距

在视口周围添加边距以在元素进入之前/之后触发操作:

blade
<!-- 在进入视口前 200px 触发 -->
<div wire:intersect.margin.200px="loadMore">...</div>

<!-- 使用基于百分比的边距 -->
<div wire:intersect.margin.10%="loadMore">...</div>

<!-- 每侧不同的边距(上、右、下、左) -->
<div wire:intersect.margin.10%.25px.25px.25px="loadMore">...</div>

仅触发一次

使用 .once 修饰符确保操作仅在第一次交叉时触发:

blade
<div wire:intersect.once="trackImpression">
    <!-- 操作仅触发一次,即使多次滚动经过 -->
</div>

这对于分析或跟踪特别有用,当你只想记录用户第一次看到某物时。

组合修饰符

你可以组合多个修饰符来创建精确的行为:

blade
<!-- 一半可见时加载,仅一次,带 100px 边距 -->
<div wire:intersect.once.half.margin.100px="loadSection">
    <!-- ... -->
</div>

常见用例

无限滚动

blade
<?php

use Livewire\Component;

new class extends Component
{
    public $page = 1;
    public $posts = [];

    public function mount()
    {
        $this->loadPosts();
    }

    public function loadPosts()
    {
        $newPosts = Post::latest()
            ->skip(($this->page - 1) * 10)
            ->take(10)
            ->get();

        $this->posts = array_merge($this->posts, $newPosts->toArray());
        $this->page++;
    }
};
?>

<div>
    @foreach ($posts as $post)
        <div>{{ $post['title'] }}</div>
    @endforeach

    <div wire:intersect="loadPosts">
        Loading more posts...
    </div>
</div>

延迟加载图片

blade
<?php

use Livewire\Component;

new class extends Component
{
    public $imageLoaded = false;

    public function loadImage()
    {
        $this->imageLoaded = true;
    }
};
?>

<div>
    @if ($imageLoaded)
        <img src="/path/to/image.jpg" alt="Product">
    @else
        <div wire:intersect.once="loadImage" class="bg-gray-200 h-64">
            <!-- Placeholder -->
        </div>
    @endif
</div>

跟踪可见性

blade
<div wire:intersect:enter.once="trackView" wire:intersect:leave="trackLeave">
    <!-- 跟踪用户何时查看和离开此内容 -->
</div>

与 Alpine 的 x-intersect 比较

如果你熟悉 Alpine.js,wire:intersect 的工作方式与 x-intersect 类似,但触发 Livewire 操作而不是 Alpine 表达式。修饰符和行为的设计旨在让 Alpine 用户感到熟悉。