Skip to content
全部文档

wire:intersect

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

基本用法

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

blade
<div wire:intersect="loadMore">
    <!-- Content loads when scrolled into view -->
</div>

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

进入与离开事件

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

blade
<!-- Runs when entering viewport (default) -->
<div wire:intersect="trackView">...</div>

<!-- Runs when entering viewport (explicit) -->
<div wire:intersect:enter="trackView">...</div>

<!-- Runs when leaving viewport -->
<div wire:intersect:leave="pauseVideo">...</div>

可见性修饰符

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

blade
<!-- Trigger when any part is visible (default) -->
<div wire:intersect="load">...</div>

<!-- Trigger when half is visible -->
<div wire:intersect.half="load">...</div>

<!-- Trigger when fully visible -->
<div wire:intersect.full="load">...</div>

<!-- Trigger at custom threshold (0-100) -->
<div wire:intersect.threshold.25="load">...</div>

边距

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

blade
<!-- Trigger 200px before entering viewport -->
<div wire:intersect.margin.200px="loadMore">...</div>

<!-- Use percentage-based margin -->
<div wire:intersect.margin.10%="loadMore">...</div>

<!-- Different margins for each side (top, right, bottom, left) -->
<div wire:intersect.margin.10%.25px.25px.25px="loadMore">...</div>

只触发一次

使用 .once 修饰符确保操作仅在首次相交时触发:

blade
<div wire:intersect.once="trackImpression">
    <!-- Action only fires once, even if scrolled past multiple times -->
</div>

这在分析或跟踪场景中特别有用——当你只想记录用户第一次看到某内容时。

要求持续可见

当元素必须保持可见一段时间后才运行操作时,使用 .dwell。默认停留时间为 250 毫秒:

blade
<div wire:intersect.dwell="trackView">...</div>

添加时长修饰符可选择不同间隔:

blade
<!-- Run after 500 milliseconds of continuous visibility -->
<div wire:intersect.dwell.500ms="trackView">...</div>

若元素不再满足可见性阈值,或页面转到后台,停留计时器会重置。当元素在可见页面中再次符合条件时会重新计时。

对于 wire:intersect:leave,停留间隔改为在可见性低于配置阈值之后开始:

blade
<div wire:intersect:leave.half.dwell.500ms="pauseVideo">...</div>

.dwell 与可见性阈值以及 .once 组合,可记录合格的曝光:

blade
<div wire:intersect.once.half.dwell.1000ms="trackImpression">...</div>

组合修饰符

你可以组合多个修饰符以实现精确行为:

blade
<!-- Load when half visible, only once, with 100px margin -->
<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">
    <!-- Track when users view and leave this content -->
</div>

与 Alpine 的 x-intersect 对比

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

参考

blade
wire:intersect="action"
wire:intersect:enter="action"
wire:intersect:leave="action"

修饰符

修饰符说明
.once仅在首次相交时触发操作
.dwell.[duration]要求持续可见后才触发(默认 250ms
.half元素一半可见时触发
.full元素完全可见时触发
.threshold.[0-100]在自定义可见性百分比阈值时触发
.margin.[value]在视口周围添加边距(如 .margin.200px.margin.10%
.parent在元素父级内观察可见性,而非浏览器视口
.renderless运行操作但不渲染组件
.async在并行请求中运行操作
.preserve-scroll在操作期间保留页面滚动位置