代码之家  ›  专栏  ›  技术社区  ›  Marco

滚动时在视口中显示元素

  •  3
  • Marco  · 技术社区  · 6 年前

    我一直试图在滚动条上显示一个元素,当它在视口中时,如果没有,请再次隐藏它。但不管我怎么努力,我都无法让它发挥作用。

    这是我到目前为止所拥有的,但该函数只在加载页面时运行一次,而不是在滚动页面时运行一次,因此它不会更新值。

    $(window).scroll(function() {
        var top_of_element = $("#cont_quote blockquote").offset().top;
        var bottom_of_element = $("#cont_quote blockquote").offset().top + $("#cont_quote blockquote").outerHeight();
        var bottom_of_screen = $(window).scrollTop() + window.innerHeight;
        var top_of_screen = $(window).scrollTop();
    
        if((bottom_of_screen > top_of_element) && (top_of_screen < bottom_of_element)){
           $('#cont_quote blockquote').animate({'opacity':'1'},1000);
        }
        else {
           $('#cont_quote blockquote').animate({'opacity':'0'},1000);
        }
    });
    
    
    
    <section id="cont_quote">
        <article class="cont_q">
            <blockquote>Lorem ipsum</blockquote>
        </article>
    </section>
    
    3 回复  |  直到 6 年前
        1
  •  6
  •   somethinghere    6 年前

    在纯javascript中,您可以这样做,与完全基于jQuery的方法相比,使用的资源要少得多:

    function inViewport( element ){
      
      // Get the elements position relative to the viewport
    
      var bb = element.getBoundingClientRect();
      
      // Check if the element is outside the viewport
      // Then invert the returned value because you want to know the opposite
    
      return !(bb.top > innerHeight || bb.bottom < 0);
      
    }
    
    var myElement = document.querySelector( 'div' );
    
    // Listen for the scroll event
    
    document.addEventListener( 'scroll', event => {
     
      // Check the viewport status
    
      if( inViewport( myElement ) ){
        
        myElement.style.background = 'red';
        
      } else {
        
        myElement.style.background = '';
        
      }
      
    })
    body {
      
      height: 400vh;
      
    }
    
    div {
      
      width: 50vw;
      height: 50vh;
      position: absolute;
      top: 125vh;
      left: 25vw;
      transition: background 4s;
      border: 1px solid red;
      
    }
    <p>Scroll Down</p>
    <div></div>

    下面是一个不透明度更改的片段:

    function inViewport( element ){
      
      // Get the elements position relative to the viewport
    
      var bb = element.getBoundingClientRect();
      
      // Check if the element is outside the viewport
      // Then invert the returned value because you want to know the opposite
    
      return !(bb.top > innerHeight || bb.bottom < 0);
      
    }
    
    var myElement = document.querySelector( 'div' );
    
    // Listen for the scroll event
    
    document.addEventListener( 'scroll', event => {
     
      // Check the viewport status
    
      if( inViewport( myElement ) ){
        
        myElement.style.opacity = 1;
        
      } else {
        
        myElement.style.opacity = '';
        
      }
      
    })
    body {
      
      height: 400vh;
      
    }
    
    div {
      
      width: 50vw;
      height: 50vh;
      position: absolute;
      top: 125vh;
      left: 25vw;
      transition: opacity 1s;
      opacity: .2;
      background: blue;
      
    }
    <p>向下滚动(<)/p>
    <div></div>

    这是一个片段,向您展示了如何定义它在视口中的触发位置,我刚刚更改了 innerHeight 0 值到 object 定义从顶部开始的像素量和从底部开始的像素量。不要忘记还为添加事件侦听器 resize ,因为如果视口更改,这些基于像素的值将更改,所以 myViewport 需要相应地更新对象:

    function inViewport( element, viewport = { top: 0, bottom: innerHeight } ){
      
      // Get the elements position relative to the viewport
    
      var bb = element.getBoundingClientRect();
      
      // Check if the element is outside the viewport
      // Then invert the returned value because you want to know the opposite
    
      return !(bb.top > viewport.bottom || bb.bottom < viewport.top);
      
    }
    
    var myViewport = { top: innerHeight * .4, bottom: innerHeight * .6 };
    var myElement = document.querySelector( 'div' );
    
    // Listen for the scroll event
    
    document.addEventListener( 'scroll', event => {
     
      // Check the viewport status
    
      if( inViewport( myElement, myViewport ) ){
        
        myElement.style.opacity = 1;
        
      } else {
        
        myElement.style.opacity = '';
        
      }
      
    })
    
    window.addEventListener( 'resize', event => {
     
      // Update your viewport values
    
      myViewport.top = innerHeight * .4;
      myViewport.bottom = innerHeight * .6;
      
    })
    车身{
    
    高度:400vh;
    
    }
    
    部门{
    
    宽度:50vw;
    高度:50vh;
    位置:绝对;
    顶部:125vh;
    左:25vw;
    过渡:不透明度1s;
    不透明度:.2;
    背景:蓝色;
    
    }
    <p>向下滚动(<)/p>
    <div></div>
        2
  •  0
  •   Robert Bisschop    6 年前

    尝试使用:

    $(window).on('scroll mousewheel', function() {
    

    并围绕您的功能:

    $(document).ready(function(){
    });
    
        3
  •  0
  •   Galzor    6 年前

    我只想用你的代码来解决你的问题。现在对我来说效果很好。请试试这个,让我知道。同时打开浏览器控制台,查看是否存在任何js错误。

    $(window).scroll(function() {
      var top_of_element = $("#cont_quote blockquote").offset().top;
      var bottom_of_element = $("#cont_quote blockquote").offset().top + $("#cont_quote blockquote").outerHeight();
      var bottom_of_screen = $(window).scrollTop() + window.innerHeight;
      var top_of_screen = $(window).scrollTop();
    
      if((bottom_of_screen > top_of_element) && (top_of_screen < bottom_of_element)){
        $('#cont_quote blockquote').fadeIn(1000);
        console.log('if cond');
      } else {      
        $('#cont_quote blockquote').fadeOut(1000);
        console.log('else cond');
      }
    });