简体   繁体   English

如何分别在向下/向上滚动时淡入/淡出按钮

[英]How to fade in / fade out a button on scrolling down / up respectively

I am working on my portfolio website and I am a complete beginner in Javascript.我正在我的投资组合网站上工作,我是Javascript完全初学者

I would like a button which has its position fixed, to slowly fade in when I scroll down (suppose when I scroll to >=20px from the top of the document, it should fade in) and when I scroll back up to the original position, it should gradually fade out .我想要一个位置固定按钮当我向下滚动时慢慢淡入(假设当我从文档顶部滚动到 >=20px 时,它应该淡入) ,当我向上滚动到原始位置时,应该会逐渐淡出

I have already tried my hand and written a code for this.我已经尝试过并为此编写了代码。 It is working perfectly when you scroll down and up.当您向下和向上滚动时,它运行良好。 But when you quickly scroll and stop scrolling in the mid-way, it behaves pretty abnormally (suddenly appears or disappears).但是当您快速滚动并在中途停止滚动时,它的行为非常异常(突然出现或消失)。

HTML : HTML :

<div class="a_large_page">
    <div class="enclose bordar black" id="bottomtoup">hello</div>
</div>

JS : JS

mybutton = document.getElementById("bottomtoup")

// initially, the button stays hidden
visible = false

// When the user scrolls down 20px from the top of the document, show the button
window.onscroll = function() {
  scrollFunction()
};

function scrollFunction() {
  if (document.body.scrollTop > 20 || document.documentElement.scrollTop > 20) {
    if (!visible) { // if the button is not visible,
      unfade(mybutton); // function to gradually fadein button
      visible = true; // button is visible so, set visible = false to true.
    }

  } else {

    if (visible) { // if the button is visible,
      fade(mybutton); // function to gradually fadeout button
      visible = false; // set visible = true back to false
    }


  }
}


function unfade(element) {
  var op = 0.1; // initial opacity
  element.style.display = 'flex';
  var timer = setInterval(function() {
    if (op >= 1) {
      clearInterval(timer);
    }
    element.style.opacity = op;
    element.style.filter = 'alpha(opacity=' + op * 100 + ")";
    op += op * 0.1;
  }, 10);
}


function fade(element) {
  var op = 1; // initial opacity
  var timer = setInterval(function() {
    if (op <= 0.1) {
      clearInterval(timer);
      element.style.display = 'none';
    }
    element.style.opacity = op;
    element.style.filter = 'alpha(opacity=' + op * 100 + ")";
    op -= op * 0.1;
  }, 50);
}

 

Here is the fiddle: https://jsfiddle.net/P0intMaN/Lmp6u5ft/23/这是小提琴: https : //jsfiddle.net/P0intMaN/Lmp6u5ft/23/

My code is pretty substandard for sure.我的代码肯定不合标准。 That's why it is behaving in this way.这就是它以这种方式表现的原因。 Hence, I am looking for an efficient way to achieve this.因此,我正在寻找一种有效的方法来实现这一目标。 I have seen people making use of JQuery to do this, but I don't know JQuery at all.我见过有人使用JQuery来做到这一点,但我根本不了解 JQuery。 So, it would be much appreciated if the code is in pure JS .因此,如果代码是纯 JS ,将不胜感激。

There is no need to have so much JS when you can do in so little:当你能做这么少的事情时,没有必要拥有这么多的 JS:

If you feel to change the timing of如果你觉得改变时间

 // Set a function onscroll - this will activate if the user scrolls window.onscroll = function() { // Set the height to check for var appear = 20 if (window.pageYOffset >= appear) { // If more show the element document.getElementById("bottomtop").style.opacity = '1' document.getElementById("bottomtop").style.pointerEvents = 'all' } else { // Else hide it document.getElementById("bottomtop").style.opacity = '0' document.getElementById("bottomtop").style.pointerEvents = 'none' } }
 .a_large_page{ background-color: gray; height: 2000px; } .enclose{ height: 40px; width: 40px; position:fixed; margin-right: 20px; margin-bottom: 20px; right:0; bottom:0; pointer-events:none; opacity:0; justify-content: center; align-items: center; color:white; /* This determines how fast animation takes place, you can change it as per your choice. */ transition:all 0.6s; } .enclose:hover{ cursor: pointer; }
 <div class="a_large_page"> <div class="enclose bordar black" id="bottomtop">hello</div> </div>

I've changed your code and removed setInterval usage.我已经更改了您的代码并删除了setInterval用法。 This can be solved with it but may be harder to understand for newer coders.这可以用它来解决,但对于新的编码人员来说可能更难理解。

There are also flags to keep track of whether you are currently fading or unfading to ensure you do not stack or "overlap" timeout/intervals.还有一些标志可以跟踪您当前是否正在fading或未unfading以确保您不会堆叠或“重叠”超时/间隔。

mybutton = document.getElementById("bottomtoup")

// initially, the button stays hidden
var visible = false

// When the user scrolls down 20px from the top of the document, show the button
window.onscroll = function() {
  scrollFunction()
};

function scrollFunction() {
    var threshold = 20;
    var below_threshold = document.body.scrollTop > threshold || document.documentElement.scrollTop > threshold;
  
  if (below_threshold) {
    if (!visible) { // if the button is not visible,
      unfade(mybutton); // function to gradually fadein button
    }
    
    return;
  }

  if (visible) { // if the button is visible,
    fade(mybutton); // function to gradually fadeout button
  }
}

var current_opacity = 0.1;
var is_unfading = false;
var is_fading = false;

function unfade(element) {
    if(!visible){
    element.style.display = 'flex';
    visible = true;
  }
  
  is_fading = false;
  is_unfading = true;
  
  unfade_step(element);
}

function unfade_step(element){
    element.style.opacity = current_opacity;
    element.style.filter = 'alpha(opacity=' + current_opacity * 100 + ")";
    
    if (current_opacity >= 1){
        // end
      is_unfading = false;
      current_opacity = 1;
        return;
    }
    
    current_opacity += 0.01;
    if(is_unfading){
      setTimeout(function(){
        unfade_step(element);
      }, 10);
    }
}

function fade(element) {
    if(!visible){
    return;
  }
  
  is_fading = true;
  is_unfading = false;
  
  fade_step(element);
}


function fade_step(element) {
    element.style.opacity = current_opacity;
    element.style.filter = 'alpha(opacity=' + current_opacity * 100 + ")";
    
    if (current_opacity <= 0.001){
        // end
      is_fading = false;
      visible = false;
      current_opacity = 0.1;
        element.style.display = 'none';
        return;
    }
    
    current_opacity -= 0.01;
    if(is_fading){
      setTimeout(function(){
        fade_step(element);
      }, 10);
    }
}

There is no need to sense the scroll event in more modern browsers as you can use IntersetionObserver to tell you when scrolling has gone past 20px;无需在更现代的浏览器中感知滚动事件,因为您可以使用 IntersetionObserver 来告诉您滚动超过 20px 的时间;

You can do this by placing a tiny element at the top of the page with height 20px.您可以通过在页面顶部放置一个高度为 20 像素的小元素来实现。 You then ask the system to tell you when this has gone out of, or comes back into, the viewport.然后,您要求系统告诉您它何时离开或返回视口。 At these points you can set the opacity of the Hello to 1 or 0 as appropriate.在这些点上,您可以根据需要将 Hello 的不透明度设置为 1 或 0。

The extra bonus is that you get rid of a lot of code and there isn't the possible clash between set intervals as we use transition on the opacity to do the gradual fade in/out.额外的好处是您摆脱了大量代码,并且在设置间隔之间不会发生冲突,因为我们在不透明度上使用过渡来逐步淡入/淡出。

 // See MDN for more info on IntersectioObserver let callback = (entries, observer) => { entries.forEach(entry => { if (entry.isIntersecting) { mybutton.style.opacity = 0; } else { mybutton.style.opacity = 1; } }); }; const mybutton = document.getElementById("bottomtoup") const observer = new IntersectionObserver(callback); const observed = document.getElementById("observed"); observer.observe(observed);
 .a_large_page { background-color: gray; height: 2000px; position: relative; } #observed { position: absolute; top: 0; left: 0; height: 20px; width: 10px; z-index: -999; } .enclose { height: 40px; width: 40px; position: fixed; margin-right: 20px; margin-bottom: 20px; right: 0; bottom: 0; justify-content: center; align-items: center; color: white; opacity: 0; transition: opacity 1s linear; }
 <div class="a_large_page"> <div id="observed"></div> <div class="enclose bordar black" id="bottomtoup">hello</div> </div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM