【问题标题】:jQuery - calculate the scroll ratio of an element when it enters the veiwport?jQuery - 计算元素进入视口时的滚动率?
【发布时间】:2017-11-27 18:44:00
【问题描述】:

如何计算元素进入视点后的滚动率?

我的来自几个来源的代码组合:

$(document).ready(function(){

  var initY = $('.scrollratio').offset().top
  var height = $('.scrollratio').height()
  var endY  = initY + $('.scrollratio').height()

  $(window).scroll(function(){
    var scroll = $(window).scrollTop()

    var visible = isVisible(document.getElementById("demo"))
    console.log(visible)

    if (visible) {
      console.log('in view')
    } else {
      console.log('out of view')
    }

    if(visible){
      var diff = scroll - initY
      var ratio = Math.round((diff / height) * 100)
      $('#note').text(ratio)
    }
  })
})

// Check if the element is in the viewport.
// http://www.hnldesign.nl/work/code/check-if-element-is-visible/
function isVisible(node) {
    // Am I visible?
    // Height and Width are not explicitly necessary in visibility detection, the bottom, right, top and left are the
    // essential checks. If an image is 0x0, it is technically not visible, so it should not be marked as such.
    // That is why either width or height have to be > 0.
    var rect = node.getBoundingClientRect()
    return (
        (rect.height > 0 || rect.width > 0) &&
        rect.bottom >= 0 &&
        rect.right >= 0 &&
        rect.top <= (window.innerHeight || document.documentElement.clientHeight) &&
        rect.left <= (window.innerWidth || document.documentElement.clientWidth)
    )
}
* {
    padding: 0;
    margin: 0;
}
body, html {
  height: 100%;
  margin: 0;
  font: 400 15px/1.8 "Lato", sans-serif;
  color: #777;
}

body {
  background:#171717;
}

.section-1 {
  width: 100%;
  min-height: 100%;
}

.scrollratio {
  height: 2000px;
  background:red;
}

#note {
  position: fixed;
  top: 0;
  left: 0;
  color: #FFFFFF;
  margin: 2em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="note" ></div>
<div class="section-1"></div>
<br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br>
<div class="scrollratio" id="demo"></div>
<br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br>

当元素(红色框)进入视口时获取负值在元素顶部开始越过窗口顶部时获取正值。

任何想法如何在元素进入视口后立即获得正值

编辑:

$(document).ready(function(){

  var initY = $('.scrollratio').offset().top
  var height = $('.scrollratio').height()
  var endY  = initY + $('.scrollratio').height()
  var wHeight = $(window).height();

  $(window).scroll(function(){
    var scroll = $(window).scrollTop()

    var visible = isVisible(document.getElementById("demo"))

    if(visible){
      var diff = scroll + wHeight - initY
      var ratio = Math.round((diff / height) * 100)
      $('#note').text(ratio)
    }
  })
})

// Check if the element is in the viewport.
// http://www.hnldesign.nl/work/code/check-if-element-is-visible/
function isVisible(node) {
    // Am I visible?
    // Height and Width are not explicitly necessary in visibility detection, the bottom, right, top and left are the
    // essential checks. If an image is 0x0, it is technically not visible, so it should not be marked as such.
    // That is why either width or height have to be > 0.
    var rect = node.getBoundingClientRect()
    return (
        (rect.height > 0 || rect.width > 0) &&
        rect.bottom >= 0 &&
        rect.right >= 0 &&
        rect.top <= (window.innerHeight || document.documentElement.clientHeight) &&
        rect.left <= (window.innerWidth || document.documentElement.clientWidth)
    )
}
* {
    padding: 0;
    margin: 0;
}
body, html {
  height: 100%;
  margin: 0;
  font: 400 15px/1.8 "Lato", sans-serif;
  color: #777;
}

body {
  background:#171717;
}

.section-1 {
  width: 100%;
  min-height: 100%;
}

.scrollratio {
  height: 2000px;
  background:red;
}

#note {
  position: fixed;
  top: 0;
  left: 0;
  color: #FFFFFF;
  margin: 2em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<div id="note" ></div>
<div class="scrollratio" id="demo"></div>
<br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br>

【问题讨论】:

    标签: javascript jquery scroll viewport


    【解决方案1】:

    我想这仅仅是因为您还没有考虑到窗口的高度。只需将var wHeight = $(window).height(); 添加到您的计算中,我相信它已经解决了。见下文。另请注意,我已经在滚动事件之外添加了 wheight 变量,因为每次都不需要调用它 - 但是,您可能需要考虑窗口调整大小并在这种情况下更新变量。
    PS:我在var diff =的计算中添加了wHeight变量

    编辑:根据要求,我更新了下面的 javascript,根据它是否在“第一个”窗口高度内有条件地设置 wHeight

        $(document).ready(function(){
    
      var initY = $('.scrollratio').offset().top
      var height = $('.scrollratio').height()
      var endY  = initY + $('.scrollratio').height();
    
      if(initY > $(window).height()){
      wHeight = $(window).height();
      } else {
      wHeight = 0;
      };
    
      $(window).scroll(function(){
        var scroll = $(window).scrollTop()
        var visible = isVisible(document.getElementById("demo"));
    
        if(visible){
          var diff = scroll + wHeight - initY
          var ratio = Math.round((diff / height) * 100);
          $('#note').text(ratio)
        }
      })
    })
    
    // Check if the element is in the viewport.
    // http://www.hnldesign.nl/work/code/check-if-element-is-visible/
    function isVisible(node) {
        // Am I visible?
        // Height and Width are not explicitly necessary in visibility detection, the bottom, right, top and left are the
        // essential checks. If an image is 0x0, it is technically not visible, so it should not be marked as such.
        // That is why either width or height have to be > 0.
        var rect = node.getBoundingClientRect()
        return (
            (rect.height > 0 || rect.width > 0) &&
            rect.bottom >= 0 &&
            rect.right >= 0 &&
            rect.top <= (window.innerHeight || document.documentElement.clientHeight) &&
            rect.left <= (window.innerWidth || document.documentElement.clientWidth)
        )
    }
    * {
        padding: 0;
        margin: 0;
    }
    body, html {
      height: 100%;
      margin: 0;
      font: 400 15px/1.8 "Lato", sans-serif;
      color: #777;
    }
    
    body {
      background:#171717;
    }
    
    .section-1 {
      width: 100%;
      min-height: 100%;
    }
    
    .scrollratio {
      height: 2000px;
      background:red;
    }
    
    #note {
      position: fixed;
      top: 0;
      left: 0;
      color: #FFFFFF;
      margin: 2em;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    
    <div id="note" ></div>
    <div class="section-1"></div>
    <br><br><br><br><br><br><br><br><br><br><br>
    <br><br><br><br><br><br><br><br><br><br><br>
    <div class="scrollratio" id="demo"></div>
    <br><br><br><br><br><br><br><br><br><br><br>
    <br><br><br><br><br><br><br><br><br><br><br>
    <br><br><br><br><br><br><br><br><br><br><br>
    <br><br><br><br><br><br><br><br><br><br><br>

    如果您想让脚本“防调整大小”并避免在initY &lt; $(window).height() 的情况下使用负数,您可以执行以下操作(依赖于全局变量):

    $(document).ready(function(){
     function setVars(){
      initY = $('.scrollratio').offset().top
      height = $('.scrollratio').height()
      endY  = initY + $('.scrollratio').height();
    
      if(initY > $(window).height()){
      wHeight = $(window).height();
      } else {
      wHeight = 0;
      };
    };
    setVars();
      $(window).scroll(function(){
        var scroll = $(window).scrollTop()
        var visible = isVisible(document.getElementById("demo"));
    
        if(visible){
          var diff = scroll + wHeight - initY;
          var ratio = Math.round((diff / height) * 100);
          if(ratio >= 0){
            $('#note').text(ratio);
          };
        }
      })
     $(window).on("resize", setVars);
    })
    
    // Check if the element is in the viewport.
    // http://www.hnldesign.nl/work/code/check-if-element-is-visible/
    function isVisible(node) {
        // Am I visible?
        // Height and Width are not explicitly necessary in visibility detection, the bottom, right, top and left are the
        // essential checks. If an image is 0x0, it is technically not visible, so it should not be marked as such.
        // That is why either width or height have to be > 0.
        var rect = node.getBoundingClientRect()
        return (
            (rect.height > 0 || rect.width > 0) &&
            rect.bottom >= 0 &&
            rect.right >= 0 &&
            rect.top <= (window.innerHeight || document.documentElement.clientHeight) &&
            rect.left <= (window.innerWidth || document.documentElement.clientWidth)
        )
    }
    

    【讨论】:

    • 感谢您的帮助!
    • 我猜它有一个小错误 - 当红色框位于顶部时(没有section-1),它获得的值从 10 或 40 以上开始,而不是从 0。请参阅我的编辑以上。
    • 嗯,这将取决于您对这个比率的目标。包括窗口高度显示当 div 从底部进入屏幕时(滚动到它时),比率应该为 0。当 section-1 被删除时,div 已经在屏幕的顶部,因此比率 > 0。但是“适应”这两种需求的一种方法是使 wHeight 有条件 - 请参阅更新的答案秒
    • @laukok 更新了答案 - 花了一秒钟多一点 :)
    • 还添加了进一步的更新以考虑调整大小和负数的可能性
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多