0

我有一个简单的 JS 代码,在用户从顶部滚动某个数字(在本例中为 400)然后淡入所述元素后,我尝试淡出某个元素(ID 为“intro-section”的标签)当用户从顶部超过某些像素时。

这是我正在使用的 JS、JQuery 代码:

问题是,fadeTo() 函数仅在很长一段时间后才显示动画效果(淡出在我越过 400px 标记后 20 秒开始,而在我回去后淡入过程,又开始20 秒)。我希望它在超过 400 像素或小于 400 像素后立即淡入和淡出。(我不想使用fadeIn() 和fadeOut() 函数,因为它们将显示设置为无)。

这是整个过程的一分钟视频: https ://imgur.com/a/lXQcgWB

我不确定 fadeTo() 是否有某种自动添加的延迟,或者我做错了什么。

$(document).scroll(function() {
  var y = $(this).scrollTop();
  console.log(y);

  if (y > 400) {
    console.log('fading out');
    $('#intro-section').fadeTo(400, 0.0);
    console.log('done fading out');
  } else {
    console.log('fading in');
    $('#intro-section').fadeTo(400, 1.0);
    console.log('done fading in');
  }
});
body {
  height: 1000px;
}

#intro-section {
  padding: 2rem;
  height: 200px;
  width: 200px;
  background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

  <body>
<div style="height: 300px">
  Scroll down!
</div>

<div id="intro-section">
  Intro
</div>

<div style="height: 100vh">
</div>
  </body>

4

3 回答 3

1

我尝试了很多时间,也许这就是你要找的:)

let fadeInning = true;
let fadeOuting = false;
$(document).scroll(function() {
  var y = $(this).scrollTop();
  console.log(y);
  if (y > 400) {
    if(!fadeOuting){
      fadeOuting = true;
      if(fadeInning){
        setTimeout(()=>{
          fadeInning = false;
          console.log('fading out');
          $('#intro-section').fadeTo(400, 0.0);
          console.log('done fading out');
        }, 400);
      }
      else{
        fadeInning = false;
        console.log('fading out');
        $('#intro-section').fadeTo(400, 0.0);
        console.log('done fading out');
      }
    }
  }
  else{
    if(!fadeInning){
      fadeInning = true;
      if(fadeOuting){
        setTimeout(()=>{
          fadeOuting = false;
          console.log('fading in');
          $('#intro-section').fadeTo(400, 1.0);
          console.log('done fading out');
        }, 400);
      }
      else{
        fadeOuting = false;
        console.log('fading in');
        $('#intro-section').fadeTo(400, 1.0);
        console.log('done fading in');
      }
    }
  }
});
body {
  height: 1000px;
}

#intro-section {
  padding: 2rem;
  height: 200px;
  width: 200px;
  background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div style="height: 300px">
  Scroll down!
</div>

<div id="intro-section">
  Intro
</div>

<div style="height: 100vh">
</div>

于 2020-09-24T16:23:59.447 回答
1

您在滚动时多次调用 FadeTo,因此当它尝试淡入时它仍然会淡出。此代码经过测试并且可以正常工作。

let fading = false;

jQuery(document).scroll(function() {
    var y = jQuery(this).scrollTop();
    console.log(y);
    if(!fading) {
        fading = true;
        if (y > 400) {
            console.log('fading out');
            jQuery('#intro-section').fadeTo(400, 0.0, () => fading = false);
            console.log('done fading out');
        } else {
            console.log('fading in');
            jQuery('#intro-section').fadeTo(400, 1.0, () => fading = false);
            console.log('done fading in');
        }
    }


});
于 2020-09-24T14:37:17.770 回答
1

问题是你总是打电话fadeTo(),即使你不需要。当您滚动通过时y > 400fadeTo(400, 0)淡出)被调用。但是,当您进一步向下滚动时,fadeTo(400, 0)即使该元素不再可见,您也会继续调用。

我不完全确定为什么淡出需要这么长时间,但我想这与在短时间内链接大量动画请求有关。

您可以通过跟踪元素的可见性来解决问题。我添加了以下内容:

if (y <= 400 == isVisible) return;

// or if you find the above confusing
if (y <= 400 && isVisible || y > 400 && !isVisible) return;

如果不必更改可见性,则会提前退出回调。此保护子句确保fadeTo()仅在实际需要时才调用它。

有助于提高性能的另一件事是确保$("#intro-section")事先保存在变量中。您不应该忘记,这$()是一个每次调用时都必须在 DOM 中搜索提供的查询选择器的函数。想象它为findSelectorInDOM("#intro-section"). 将结果缓存在变量中可能会大大加快速度,尤其是当您$()经常使用相同的参数调用时。

const $introSection = $("#intro-section");
let isVisible = $introSection.is(":visible");

$(document).scroll(function() {
  const y = $(this).scrollTop();
  console.log(y);
  
  if (y <= 400 == isVisible) return;  
  isVisible = !isVisible;
  const opacity = +isVisible;
  
  console.log(`start fading to ${opacity}`);
  $introSection.fadeTo(400, opacity, () => {
    console.log(`done fading to ${opacity}`);
  });
});
#intro-section {
  padding: 4rem;
}

#intro-section .row {
  padding: 4rem 8rem 7rem 8rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div style="height: 300px">
  Scroll down!
</div>

<div id="intro-section">
  Intro
</div>

<div style="height: 100vh">
</div>

于 2020-09-24T16:21:05.733 回答