You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Div或CSS类进入浏览器视口时执行jQuery函数且仅运行一次

实现元素进入视口时触发单次jQuery函数

嘿,作为jQuery新手能想到这个需求很棒!你想要的是当目标元素(或者整个容器)进入浏览器视口时,触发一次计数动画,而且确保动画只运行一次对吧?我来帮你调整代码实现这个功能,顺便解释其中的关键点。

核心思路

要实现这个需求,我们需要做到三点:

  • 准确判断元素是否进入了视口
  • 确保函数只触发一次(给元素加个“已执行”的标记)
  • 在滚动/窗口 resize 时监听状态变化(但要避免频繁触发)

修改后的完整代码

HTML 部分

<div id="fico_scroll">
  <div id="fico-11"><span class="count">495</span></div>
  <div id="fico-2"><span class="count">722</span></div>
  <div id="fico-3"><span class="count">608</span></div>
  <div id="fico-4"><span class="count">805</span></div>
  <div id="fico-5"><span class="count">533</span></div>
  <div id="fico-6"><span class="count">685</span></div>
  <div style="clear:both"></div>
</div>

jQuery 部分

// 自定义插件:判断元素是否在视口内
$.fn.isInViewport = function() {
  var elementTop = $(this).offset().top;
  var elementBottom = elementTop + $(this).outerHeight();
  var viewportTop = $(window).scrollTop();
  var viewportBottom = viewportTop + $(window).height();
  // 这里可以微调判断条件,比如元素进入视口一半时触发
  return elementBottom > viewportTop && elementTop < viewportBottom;
};

// 定义触发动画的函数
function animateCounter($element) {
  $element.prop('Counter', 0).animate({
    Counter: $element.text()
  }, {
    duration: 4000,
    easing: 'swing',
    step: function(now) {
      $(this).text(Math.ceil(now));
    }
  });
}

// 监听滚动和窗口 resize 事件
$(window).on('resize scroll', function() {
  // 遍历所有.count元素
  $('.count').each(function() {
    var $this = $(this);
    // 判断:元素在视口内,且还没执行过动画
    if ($this.isInViewport() && !$this.hasClass('animated')) {
      $this.addClass('animated'); // 添加标记,避免重复执行
      animateCounter($this); // 触发动画
    }
  });
});

关键细节解释

  1. 视口判断插件:isInViewport 函数通过对比元素的位置和视口的位置,返回元素是否在可见区域内,你可以根据需求微调判断条件(比如元素进入视口1/2时再触发)。
  2. 单次执行控制:我们给已经执行过动画的元素添加 animated 类,每次判断时先检查这个类是否存在,确保动画只运行一次。
  3. 事件监听优化:如果页面滚动频繁,scroll 事件会触发很多次,你可以加入防抖函数来优化性能(比如设置200ms的延迟,避免频繁执行判断逻辑),示例如下:
// 防抖函数
function debounce(func, delay) {
  let timer;
  return function() {
    clearTimeout(timer);
    timer = setTimeout(func, delay);
  };
}

// 使用防抖包装监听逻辑
$(window).on('resize scroll', debounce(function() {
  $('.count').each(function() {
    var $this = $(this);
    if ($this.isInViewport() && !$this.hasClass('animated')) {
      $this.addClass('animated');
      animateCounter($this);
    }
  });
}, 200));

扩展:针对整个容器触发

如果你想当整个 #fico_scroll 容器进入视口时,一次性触发所有计数器动画,只需要调整监听逻辑:

$(window).on('resize scroll', debounce(function() {
  var $container = $('#fico_scroll');
  if ($container.isInViewport() && !$container.hasClass('animated')) {
    $container.addClass('animated');
    $('.count', $container).each(function() {
      animateCounter($(this));
    });
  }
}, 200));

这样就能确保整个容器进入视口后,所有计数动画只执行一次啦!

内容的提问来源于stack exchange,提问作者Skillz-limited

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:39:44