主题
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>这对于分析或跟踪特别有用,当你只想记录用户第一次看到某些内容时。
组合修饰符
你可以组合多个修饰符以创建精确的行为:
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 | 仅在第一次交叉时触发操作 |
.half | 当元素一半可见时触发 |
.full | 当整个元素可见时触发 |
.threshold.[0-100] | 在自定义可见性阈值百分比时触发 |
.margin.[value] | 在视口周围添加边距(例如,.margin.200px、.margin.10%) |