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

为何条件语句赋值后变量仍为undefined?(jQuery滚动场景)

问题

我想要实现元素进入浏览器视口后,随scrollTop的移动同步位移,需要捕获初始scrollTop值用于后续计算。但问题是,尽管已在函数的条件语句中为变量赋值,该变量仍始终为undefined。我推测是作用域问题,以下是我的代码:

jQuery(document).ready(function($){

  //function that indicates object is in view
  $.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;
  };

  //add class when object in is view
  jQuery(window).bind('scroll',function(e){
    if ($('.home-col-01-image').isInViewport()) {
      $('.home-col-01-image').addClass("in-view")
    } else {
      $('.home-col-01-image').removeClass("in-view")
    }
  });

  //use scrollTop to move object in parallel
  jQuery(window).bind('scroll',function(e){
    if ($(".home-col-01-image").hasClass("in-view")) {
      console.log("First initialSt: " + initialSt )
      if(initialSt == undefined) {
        var initialSt = $(this).scrollTop();
        console.log("Set initialSt: " + initialSt )
      } else {
        console.log("not set initialSt: " + initialSt)
      }
      //console.log("in: ")
      var st = $(this).scrollTop();
      var nst = st - initialSt;
      //var nst = Math.abs(initialSt - st)
      console.log("Use initialSt: " + initialSt)
      console.log("scrollTop: " + st)
      console.log("New scrollTop: " + nst)
      if ((nst<=170) && (nst>=0)) {
        $(".home-col-01-image").css("bottom", + nst);
      }
    } else {
      //console.log("out: ")
    }

 });


});

控制台输出示例:

First initialSt: undefined
Set initialSt: 1047
Use initialSt: 1047
scrollTop: 1047
New scrollTop: 0
First initialSt: undefined
Set initialSt: 1048
Use initialSt: 1048
scrollTop: 1048
New scrollTop: 0

首次输出时initialSt为undefined是正常的,但后续它应该保持已赋值的状态,可实际每次都是undefined。我的核心问题是变量无法被正确赋值,暂不关注代码优化。

解决方案

问题出在变量作用域上:你在滚动事件的回调函数内部用var声明了initialSt,这意味着每次触发滚动事件时,这个变量都是当前函数作用域内的新变量,函数执行完毕后就会被销毁,下次滚动触发时又重新创建,所以永远是undefined。

要解决这个问题,需要把initialSt的声明提升到滚动回调函数的外部,让它处于jQuery(document).ready的作用域内,这样就能在多次滚动回调中保留值。

修改后的代码如下:

jQuery(document).ready(function($){
  // 把initialSt声明在全局ready作用域下,让所有滚动回调都能访问
  var initialSt;

  //function that indicates object is in view
  $.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;
  };

  //add class when object in is view
  jQuery(window).bind('scroll',function(e){
    if ($('.home-col-01-image').isInViewport()) {
      $('.home-col-01-image').addClass("in-view")
    } else {
      $('.home-col-01-image').removeClass("in-view")
      // 可选:元素离开视口时重置initialSt,下次进入时重新捕获
      initialSt = undefined;
    }
  });

  //use scrollTop to move object in parallel
  jQuery(window).bind('scroll',function(e){
    if ($(".home-col-01-image").hasClass("in-view")) {
      console.log("First initialSt: " + initialSt )
      if(initialSt == undefined) {
        initialSt = $(this).scrollTop(); // 这里不再用var声明,直接赋值
        console.log("Set initialSt: " + initialSt )
      } else {
        console.log("not set initialSt: " + initialSt)
      }
      var st = $(this).scrollTop();
      var nst = st - initialSt;
      console.log("Use initialSt: " + initialSt)
      console.log("scrollTop: " + st)
      console.log("New scrollTop: " + nst)
      if ((nst<=170) && (nst>=0)) {
        $(".home-col-01-image").css("bottom", + nst);
      }
    }
 });
});

关键修改点:

  • 在ready函数最顶部声明var initialSt;,让它处于所有滚动回调的父作用域中
  • 在滚动回调里赋值时去掉var,避免重新声明局部变量
  • 可选:在元素离开视口时重置initialSt,确保下次进入视口时能重新捕获初始scrollTop值

内容的提问来源于stack exchange,提问作者ells.eastwood

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 14:37:16