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

DIVI框架下JavaScript中IF语句无法获取函数返回值问题

问题描述

我是初级开发者,正在使用DIVI框架实现元素进入用户视口时触发动画的功能。此前已有成功经验,但简化代码后,check_if_in_view函数的返回值无法被IF语句捕获,始终返回false。使用$().each循环是因为存在多个不同ID的元素,不使用该循环会出现无法读取元素顶部位置的错误。需要问题解决方法及性能优化建议。

全局JS代码

//Getting element and window parameters
var $window = $(window);
function check_if_in_view(el) { //Da finire
  var $element = $(el);
  var window_height = $window.height();
  var window_top_position = $window.scrollTop();
  var window_bottom_position = (window_top_position + window_height);
  $(el).each(function() {
    var element_height = $(this).outerHeight();
    var element_top_position = $(this).offset().top;
    var element_bottom_position = (element_top_position + element_height);
    console.log($(this).attr('id'));
    //check to see if this current container is within viewport
    if ((element_bottom_position >= window_top_position) &&
        (element_top_position <= window_bottom_position)) {
      console.log('true');
      return true;
    } else {
      console.log('false');
      return false;
    }
  });
};

页面专属JS代码

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>

<script>
  $('.fadeInLeft').css({'right' : '700px', 'opacity' : '0'});
  $('.fadeInRight').css({'left' : '700px', 'opacity' : '0'});

  function animateFadeLeft(el) {
    $(el).each(function() {
      if(check_if_in_view($(this))) {
        console.log('sono dentro')
        $(this).animate({right: '0px', opacity : '1'}, 1200);
      }
    });
  }

  $(window).on('DOMContentLoaded load resize scroll', function(){
    animateFadeLeft('.fadeInLeft');
    animateFadeLeft('.fadeInRight'); //To add
  });
</script>
问题解决方法

核心原因

check_if_in_view函数里的$(el).each()循环中,return true/false仅会终止当前循环的单次迭代,不会将值返回给外层的check_if_in_view函数,导致外层函数默认返回undefined,在IF判断中被识别为false。

另外,你在调用check_if_in_view时,已经是在animateFadeLeft的each循环中传入单个元素($(this)),所以check_if_in_view内部完全不需要再做each循环。

修复后的check_if_in_view函数

var $window = $(window);
function check_if_in_view(el) {
  var $element = $(el);
  var window_height = $window.height();
  var window_top_position = $window.scrollTop();
  var window_bottom_position = window_top_position + window_height;

  var element_height = $element.outerHeight();
  var element_top_position = $element.offset().top;
  var element_bottom_position = element_top_position + element_height;

  // 直接返回视口判断结果
  return (element_bottom_position >= window_top_position) && (element_top_position <= window_bottom_position);
};

修复后,函数会直接返回布尔值,IF语句就能正确捕获结果,触发动画逻辑。

性能优化建议
  • 避免重复计算窗口参数:窗口高度、滚动位置在每次事件触发时只需计算一次,不需要在每个元素的检查函数里重复计算。可以把这些参数提前算出后传递给检查函数,减少冗余计算:

    $(window).on('DOMContentLoaded load resize scroll', function(){
      // 一次性计算窗口参数
      var window_height = $window.height();
      var window_top_position = $window.scrollTop();
      var window_bottom_position = window_top_position + window_height;
    
      animateFadeLeft('.fadeInLeft', window_top_position, window_bottom_position);
      animateFadeLeft('.fadeInRight', window_top_position, window_bottom_position);
    });
    
    // 修改动画函数,接收窗口参数
    function animateFadeLeft(el, windowTop, windowBottom) {
      $(el).each(function() {
        if(check_if_in_view($(this), windowTop, windowBottom)) {
          $(this).animate({right: '0px', opacity : '1'}, 1200);
        }
      });
    }
    
    // 修改检查函数,接收窗口参数
    function check_if_in_view(el, windowTop, windowBottom) {
      var $element = $(el);
      var element_height = $element.outerHeight();
      var element_top_position = $element.offset().top;
      var element_bottom_position = element_top_position + element_height;
    
      return (element_bottom_position >= windowTop) && (element_top_position <= windowBottom);
    }
    
  • 防止动画重复触发:给已完成动画的元素添加标记(比如自定义数据属性),避免滚动时反复执行动画逻辑:

    function animateFadeLeft(el, windowTop, windowBottom) {
      $(el).each(function() {
        // 检查是否已执行过动画
        if(!$(this).data('animated') && check_if_in_view($(this), windowTop, windowBottom)) {
          $(this).data('animated', true).animate({right: '0px', opacity : '1'}, 1200);
        }
      });
    }
    
  • 节流事件触发频率:滚动、resize事件触发极频繁,用节流函数限制处理逻辑的执行频率(比如每100ms执行一次),降低性能消耗:

    // 简单节流函数实现
    function throttle(func, delay) {
      let lastExecuteTime = 0;
      return function(...args) {
        const now = Date.now();
        if(now - lastExecuteTime >= delay) {
          lastExecuteTime = now;
          func.apply(this, args);
        }
      }
    }
    
    // 用节流包裹事件处理函数
    $(window).on('DOMContentLoaded load resize scroll', throttle(function(){
      var window_height = $window.height();
      var window_top_position = $window.scrollTop();
      var window_bottom_position = window_top_position + window_height;
    
      animateFadeLeft('.fadeInLeft', window_top_position, window_bottom_position);
      animateFadeLeft('.fadeInRight', window_top_position, window_bottom_position);
    }, 100));
    
  • 优先使用CSS动画:CSS动画性能优于JS动画,建议用transition或@keyframes配合类名切换实现动画:

    .fadeInLeft {
      right: 700px;
      opacity: 0;
      transition: all 1.2s ease;
    }
    .fadeInLeft.active {
      right: 0;
      opacity: 1;
    }
    
    .fadeInRight {
      left: 700px;
      opacity: 0;
      transition: all 1.2s ease;
    }
    .fadeInRight.active {
      left: 0;
      opacity: 1;
    }
    

    对应的JS逻辑简化为:

    function animateFadeLeft(el, windowTop, windowBottom) {
      $(el).each(function() {
        if(!$(this).hasClass('active') && check_if_in_view($(this), windowTop, windowBottom)) {
          $(this).addClass('active');
        }
      });
    }
    

内容的提问来源于stack exchange,提问作者Leonardo Di Silvestre

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 07:47:42