ACF重复器视差问题:实现仅进入视口时触发视动效
问题:ACF重复器视差块滚动时位置错乱
我用ACF创建了带图文切换布局、背景设置的图文块,可在WordPress页面中通过ACF重复器复制。但所有重复的视差图片块会随页面滚动同时触发动效,导致位置错乱。需要修改代码让视差仅在进入视口时激活,每个视差块独立运行。
第一步:修改PHP代码(解决重复ID冲突+添加必要标记)
原代码中重复使用id会导致DOM选择器冲突,需替换为class并保留自定义属性:
<?php if ($bgColour == 'yes') : ?> <div class="bg-primary pseudo-100 py-5 z-n1"> <?php endif; ?> <div class="row align-items-center"> <div class="col-12 col-md-6 <?= $directionTxt; ?> <?= $overTxt; ?>"><?= $text; ?> <?php $link = get_field('button'); if ($link) : $link_url = $link['url']; $link_title = $link['title']; $link_target = $link['target'] ? $link['target'] : '_self'; ?> <a class="button" href="<?php echo esc_url($link_url); ?>" target="<?php echo esc_attr($link_target); ?>"><?php echo esc_html($link_title); ?></a> <?php endif; ?> </div> <div class="col-12 col-md-6 position-relative <?= $directionImage; ?> <?= $overImg; ?>"> <!-- 替换id为class,保留data-speed自定义速度属性 --> <div class="parallax-container" data-speed="0.5"> <div></div> <?php if ($backgroundColourBlock == 'yes') : ?> <div class="parallax-bg parallax-item"></div> <?php endif; ?> <div class="middle-image parallax-item"><?= wp_get_attachment_image($imageTwo, 'large'); ?></div> <div class="front-image parallax-item"><?= wp_get_attachment_image($imageOne, 'large'); ?></div> </div> </div> </div> <?php if ($bgColour == 'yes') : ?> </div> <?php endif; ?>
修改说明:
- 将所有重复出现的
id替换为class,避免DOM冲突 - 保留
data-speed属性,支持后续JS读取自定义视差速度
第二步:修改JavaScript代码(视口检测+独立控制每个视差块)
替换原JS,实现视口内激活、独立计算偏移量:
// 检测元素是否进入视口的工具函数 function isInViewport(element) { const rect = element.getBoundingClientRect(); return rect.top < window.innerHeight && rect.bottom > 0; } window.addEventListener('scroll', () => { // 获取所有视差容器 const parallaxContainers = document.querySelectorAll('.parallax-container'); parallaxContainers.forEach(container => { // 仅处理进入视口的容器 if (!isInViewport(container)) return; const children = container.querySelectorAll('.parallax-item'); // 获取容器相对于文档顶部的位置 const containerTop = container.offsetTop; // 计算容器在视口中的滚动进度百分比 const scrollProgress = (window.scrollY - containerTop + window.innerHeight) / (container.offsetHeight + window.innerHeight); children.forEach((child, index) => { // 读取自定义速度,默认0.5 const speed = parseFloat(container.dataset.speed) || 0.5; // 基于容器自身滚动进度计算偏移量,实现独立动效 const translateY = 200 - (scrollProgress * 400 * speed * ((index + 1) / children.length)); child.style.transform = `translateY(${translateY}px)`; }); }); }, false); // 页面加载时触发一次滚动,确保初始状态正确 window.dispatchEvent(new Event('scroll'));
修改说明:
- 添加
isInViewport函数,仅对进入视口的视差块应用动效 - 使用
querySelectorAll批量获取所有视差容器,替代单一ID选择 - 基于每个容器自身的位置计算偏移量,而非全局滚动值,实现独立运行
- 支持通过
data-speed属性自定义每个视差块的动效速度 - 页面加载时触发滚动事件,避免初始状态异常
内容的提问来源于stack exchange,提问作者RuntyBeef
相关产品推荐
相关产品推荐

