【问题标题】:How to check if element is visible after scrolling?如何检查滚动后元素是否可见?
【发布时间】:2010-10-03 23:28:00
【问题描述】:

我正在通过 AJAX 加载元素。其中一些只有在您向下滚动页面时才可见。有什么方法可以知道某个元素现在是否在页面的可见部分中?

【问题讨论】:

  • 他的意思是他想要一个方法来知道给定元素是否显示在浏览器窗口中,或者用户是否需要滚动才能看到它。
  • 要检查一个元素是否在容器中完全可见,只需添加一个额外的选择器参数并重新使用它的 elem 代码。 Library.IsElementVisibleInContainer = function (elementSelector, containerSelector) { var containerViewTop = $(containerSelector).offset().top; var containerViewBottom = containerViewTop + $(containerSelector).height();
  • 所有答案都会触发重排,所以它可能是瓶颈,如果支持,您可以使用IntersectionObserver。它将在现代浏览器上具有更好的性能,

标签: javascript jquery scroll


【解决方案1】:

这应该可以解决问题:

function isScrolledIntoView(elem)
{
    var docViewTop = $(window).scrollTop();
    var docViewBottom = docViewTop + $(window).height();

    var elemTop = $(elem).offset().top;
    var elemBottom = elemTop + $(elem).height();

    return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}

简单实用功能 这将允许您调用一个实用函数,该函数接受您正在寻找的元素以及您希望该元素是完全可见还是部分可见。

function Utils() {

}

Utils.prototype = {
    constructor: Utils,
    isElementInView: function (element, fullyInView) {
        var pageTop = $(window).scrollTop();
        var pageBottom = pageTop + $(window).height();
        var elementTop = $(element).offset().top;
        var elementBottom = elementTop + $(element).height();

        if (fullyInView === true) {
            return ((pageTop < elementTop) && (pageBottom > elementBottom));
        } else {
            return ((elementTop <= pageBottom) && (elementBottom >= pageTop));
        }
    }
};

var Utils = new Utils();

用法

var isElementInView = Utils.isElementInView($('#flyout-left-container'), false);

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

【讨论】:

  • 请注意,这仅在文档是正在滚动的元素时才有效,即您没有检查滚动内部窗格中某些元素的可见性。
  • 对于:“视图中元素的任何部分”,我使用: ((( elemTop >= docViewTop) && (elemTop = docViewTop) && ( elemBottom
  • 当元素在打开的文档中时,这工作正常,当用于某些可滚动分区内的元素时,这会产生不适当的结果,我尝试用 $("somediv") 替换 $(window) 仍然没有准确的结果,我该如何得到准确的结果?。
【解决方案2】:

This answer 原版:

function isScrolledIntoView(el) {
    var rect = el.getBoundingClientRect();
    var elemTop = rect.top;
    var elemBottom = rect.bottom;

    // Only completely visible elements return true:
    var isVisible = (elemTop >= 0) && (elemBottom <= window.innerHeight);
    // Partially visible elements return true:
    //isVisible = elemTop < window.innerHeight && elemBottom >= 0;
    return isVisible;
}

【讨论】:

  • 不应该是isVisible = elementTop &lt; window.innerHeight &amp;&amp; elementBottom &gt;= 0吗?否则屏幕上的一半元素返回 false。
  • 没有。我检查某些元素是否在页面上完全可见。如果你想检查某个部分的可见性 - 你可以自定义这个 sn-p。
  • 我发现这个答案比选择的答案表现更好。也更简单。
  • 与批准的答案相比,这在数百个元素中的表现要好得多。
【解决方案3】:

更新:使用IntersectionObserver


到目前为止我发现的最好的方法是jQuery appear plugin。像魅力一样工作。

模仿自定义的“出现”事件,当元素滚动到视图中或以其他方式对用户可见时触发。

$('#foo').appear(function() {
  $(this).text('Hello world');
});

此插件可用于防止对隐藏或可见区域之外的内容的不必要请求。

【讨论】:

  • 这是一个很酷的插件,毫无疑问,但没有回答问题。
  • 有消失插件吗?
【解决方案4】:

使用IntersectionObserver API

(现代浏览器原生)


通过使用观察者,可以轻松高效地确定元素是否在视口中或任何可滚动容器中可见。

无需附加scroll事件和手动检查事件回调,效率更高:

// define an observer instance
var observer = new IntersectionObserver(onIntersection, {
  root: null,   // default is the viewport
  threshold: .5 // percentage of taregt's visible area. Triggers "onIntersection"
})

// callback is called on intersection change
function onIntersection(entries, opts){
  entries.forEach(entry =>  
    entry.target.classList.toggle('visible', entry.isIntersecting)
  )
}

// Use the observer to observe an element
observer.observe( document.querySelector('.box') )

// To stop observing:
// observer.unobserve(entry.target)
span{ position:fixed; top:0; left:0; }
.box{ width:100px; height:100px; background:red; margin:1000px; transition:.75s; }
.box.visible{ background:green; border-radius:50%; }
<span>Scroll both Vertically &amp; Horizontally...</span>
<div class='box'></div>

现代浏览器支持,包括移动浏览器。 IE 不支持 - View browsers support table

【讨论】:

  • Safari 是新的 IE,我现在想要实现的一切都得到了所有常青浏览器的支持......除了 safari
【解决方案5】:

这是我的纯 JavaScript 解决方案,如果它也隐藏在可滚动容器中,它也可以工作。

Demo here(也尝试调整窗口大小)

var visibleY = function(el){
  var rect = el.getBoundingClientRect(), top = rect.top, height = rect.height, 
    el = el.parentNode
  // Check if bottom of the element is off the page
  if (rect.bottom < 0) return false
  // Check its within the document viewport
  if (top > document.documentElement.clientHeight) return false
  do {
    rect = el.getBoundingClientRect()
    if (top <= rect.bottom === false) return false
    // Check if the element is out of view due to a container scrolling
    if ((top + height) <= rect.top) return false
    el = el.parentNode
  } while (el != document.body)
  return true
};

编辑 2016-03-26:我已经更新了解决方案以考虑滚动过去的元素,因此它隐藏在可滚动容器的顶部上方。 编辑 2018-10-08:更新为在屏幕上方滚动出视图时处理。

【讨论】:

【解决方案6】:

普通香草检查元素 (el) 在可滚动 div (holder) 中是否可见

function isElementVisible (el, holder) {
  holder = holder || document.body
  const { top, bottom, height } = el.getBoundingClientRect()
  const holderRect = holder.getBoundingClientRect()

  return top <= holderRect.top
    ? holderRect.top - top <= height
    : bottom - holderRect.bottom <= height
}

与 jQuery 一起使用:

var el = $('tr:last').get(0);
var holder = $('table').get(0);
var isVisible = isScrolledIntoView(el, holder);

【讨论】:

  • 在这个单页应用程序的时代,检查一个元素是否在 window 之外的其他元素中可见已变得越来越普遍。这就是为什么这个得到我的赞成。
  • 注意:如果您想根据元素的任何部分不可见(如我的情况)来返回此值,请从函数中删除 height 变量并将其用于的位置更改为0(零)。然后,如果您只隐藏了元素的“部分”,它将返回 false。
【解决方案7】:

jQuery Waypoints 插件在这里非常棒。

$('.entry').waypoint(function() {
   alert('You have scrolled to an entry.');
});

site of the plugin上有一些例子。

【讨论】:

  • 对我来说,它只适用于偏移量$('#my-div').waypoint(function() { console.log('Hello there!'); }, { offset: '100%' });
【解决方案8】:

怎么样

function isInView(elem){
   return $(elem).offset().top - $(window).scrollTop() < $(elem).height() ;
}

之后,一旦元素出现在这样的视图中,你就可以触发任何你想要的东西

$(window).scroll(function(){
   if (isInView($('.classOfDivToCheck')))
      //fire whatever you what 
      dothis();
})

这对我来说很好

【讨论】:

    【解决方案9】:

    Tweeked Scott Dowding 的酷炫功能满足我的要求- 这用于查找元素是否刚刚滚动到屏幕中,即它的顶部边缘。

    function isScrolledIntoView(elem)
    {
        var docViewTop = $(window).scrollTop();
        var docViewBottom = docViewTop + $(window).height();
        var elemTop = $(elem).offset().top;
        return ((elemTop <= docViewBottom) && (elemTop >= docViewTop));
    }
    

    【讨论】:

      【解决方案10】:

      WebResourcesDepot 前段时间写了a script to load while scrolling 使用jQuery。你可以查看他们的Live Demo Here。它们的功能最重要的是:

      $(window).scroll(function(){
        if  ($(window).scrollTop() == $(document).height() - $(window).height()){
          lastAddedLiveFunc();
        }
      });
      
      function lastAddedLiveFunc() { 
        $('div#lastPostsLoader').html('<img src="images/bigLoader.gif">');
        $.post("default.asp?action=getLastPosts&lastPostID="+$(".wrdLatest:last").attr("id"),
          function(data){
              if (data != "") {
                $(".wrdLatest:last").after(data);         
              }
            $('div#lastPostsLoader').empty();
          });
      };
      

      【讨论】:

        【解决方案11】:

        这里的大多数答案都没有考虑到元素也可以被隐藏,因为它被滚动到 div 的视图之外,而不仅仅是整个页面。

        为了覆盖这种可能性,您基本上必须检查元素是否位于其每个父元素的边界内。

        这个解决方案正是这样做的:

        function(element, percentX, percentY){
            var tolerance = 0.01;   //needed because the rects returned by getBoundingClientRect provide the position up to 10 decimals
            if(percentX == null){
                percentX = 100;
            }
            if(percentY == null){
                percentY = 100;
            }
        
            var elementRect = element.getBoundingClientRect();
            var parentRects = [];
        
            while(element.parentElement != null){
                parentRects.push(element.parentElement.getBoundingClientRect());
                element = element.parentElement;
            }
        
            var visibleInAllParents = parentRects.every(function(parentRect){
                var visiblePixelX = Math.min(elementRect.right, parentRect.right) - Math.max(elementRect.left, parentRect.left);
                var visiblePixelY = Math.min(elementRect.bottom, parentRect.bottom) - Math.max(elementRect.top, parentRect.top);
                var visiblePercentageX = visiblePixelX / elementRect.width * 100;
                var visiblePercentageY = visiblePixelY / elementRect.height * 100;
                return visiblePercentageX + tolerance > percentX && visiblePercentageY + tolerance > percentY;
            });
            return visibleInAllParents;
        };
        

        它还允许您指定它必须在每个方向上可见的百分比。
        不包括因其他因素而被隐藏的可能性,例如display: hidden

        这应该适用于所有主流浏览器,因为它只使用getBoundingClientRect。我亲自在 Chrome 和 Internet Explorer 11 中对其进行了测试。

        【讨论】:

        • 感谢您提供此代码。我想知道在这种情况下,如果您有多个嵌套的可滚​​动元素,您将如何在滚动上添加事件侦听器?好像只给window添加监听器是不够的,是不是还要遍历到最上面的父级给每个可滚动容器添加监听器?
        • @mr1031011 应该可以将处理程序添加到窗口,然后检查目标以识别滚动的容器。
        • 对,它不适用于@vanowm 给出的示例,
        • 这没有通过视口下方的按钮进行最简单的测试,错误地将按钮报告为可见:jsfiddle - 请参阅小提琴的控制台。或者这是在现实中不会发生的某种 jsfiddle iframe 限制?它也不能正确处理 &lt;html style="overflow: hidden auto; height: 100%;,这是 jQuery UI 布局插件所做的。
        【解决方案12】:

        isScrolledIntoView 是一个非常需要的功能,所以我试了一下,它适用于不高于视口的元素,但如果元素比视口大,它就不起作用。要解决此问题,请轻松更改条件

        return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
        

        到这里:

        return (docViewBottom >= elemTop && docViewTop <= elemBottom);
        

        在此处查看演示:http://jsfiddle.net/RRSmQ/

        【讨论】:

          【解决方案13】:

          这会考虑元素具有的任何内边距、边框或边距,以及大于视口本身的元素。

          function inViewport($ele) {
              var lBound = $(window).scrollTop(),
                  uBound = lBound + $(window).height(),
                  top = $ele.offset().top,
                  bottom = top + $ele.outerHeight(true);
          
              return (top > lBound && top < uBound)
                  || (bottom > lBound && bottom < uBound)
                  || (lBound >= top && lBound <= bottom)
                  || (uBound >= top && uBound <= bottom);
          }
          

          要这样称呼它:

          var $myElement = $('#my-element'),
              canUserSeeIt = inViewport($myElement);
          
          console.log(canUserSeeIt); // true, if element is visible; false otherwise
          

          【讨论】:

            【解决方案14】:

            这是另一个解决方案:

            <script type="text/javascript">
            $.fn.is_on_screen = function(){
                var win = $(window);
                var viewport = {
                    top : win.scrollTop(),
                    left : win.scrollLeft()
                };
                viewport.right = viewport.left + win.width();
                viewport.bottom = viewport.top + win.height();
            
                var bounds = this.offset();
                bounds.right = bounds.left + this.outerWidth();
                bounds.bottom = bounds.top + this.outerHeight();
            
                return (!(viewport.right < bounds.left || viewport.left > bounds.right ||    viewport.bottom < bounds.top || viewport.top > bounds.bottom));
             };
            
            if( $('.target').length > 0 ) { // if target element exists in DOM
                if( $('.target').is_on_screen() ) { // if target element is visible on screen after DOM loaded
                    $('.log').html('<div class="alert alert-success">target element is visible on screen</div>'); // log info       
                } else {
                    $('.log').html('<div class="alert">target element is not visible on screen</div>'); // log info
                }
            }
            $(window).on('scroll', function(){ // bind window scroll event
            if( $('.target').length > 0 ) { // if target element exists in DOM
                if( $('.target').is_on_screen() ) { // if target element is visible on screen after DOM loaded
                    $('.log').html('<div class="alert alert-success">target element is visible on screen</div>'); // log info
                } else {
                    $('.log').html('<div class="alert">target element is not visible on screen</div>'); // log info
                }
            }
            });
            </script>
            

            查看JSFiddle

            【讨论】:

              【解决方案15】:
              function isScrolledIntoView(elem) {
                  var docViewTop = $(window).scrollTop(),
                      docViewBottom = docViewTop + $(window).height(),
                      elemTop = $(elem).offset().top,
                   elemBottom = elemTop + $(elem).height();
                 //Is more than half of the element visible
                 return ((elemTop + ((elemBottom - elemTop)/2)) >= docViewTop && ((elemTop + ((elemBottom - elemTop)/2)) <= docViewBottom));
              }
              

              【讨论】:

                【解决方案16】:

                我需要检查可滚动 DIV 容器内元素的可见性

                    //p = DIV container scrollable
                    //e = element
                    function visible_in_container(p, e) {
                        var z = p.getBoundingClientRect();
                        var r = e.getBoundingClientRect();
                
                        // Check style visiblilty and off-limits
                        return e.style.opacity > 0 && e.style.display !== 'none' &&
                               e.style.visibility !== 'hidden' &&
                               !(r.top > z.bottom || r.bottom < z.top ||
                                 r.left > z.right || r.right < z.left);
                    }
                

                【讨论】:

                  【解决方案17】:

                  this great answer 的基础上,您可以使用 ES2015+ 进一步简化它:

                  function isScrolledIntoView(el) {
                    const { top, bottom } = el.getBoundingClientRect()
                    return top >= 0 && bottom <= window.innerHeight
                  }
                  

                  如果您不关心顶部超出窗口而只关心底部是否已被查看,则可以将其简化为

                  function isSeen(el) {
                    return el.getBoundingClientRect().bottom <= window.innerHeight
                  }
                  

                  甚至是单线

                  const isSeen = el => el.getBoundingClientRect().bottom <= window.innerHeight
                  

                  【讨论】:

                    【解决方案18】:

                    有一个plugin for jQuery called inview 添加了一个新的“inview”事件。


                    下面是一些不使用事件的 jQuery 插件的代码:

                    $.extend($.expr[':'],{
                        inView: function(a) {
                            var st = (document.documentElement.scrollTop || document.body.scrollTop),
                                ot = $(a).offset().top,
                                wh = (window.innerHeight && window.innerHeight < $(window).height()) ? window.innerHeight : $(window).height();
                            return ot > st && ($(a).height() + ot) < (st + wh);
                        }
                    });
                    
                    (function( $ ) {
                        $.fn.inView = function() {
                            var st = (document.documentElement.scrollTop || document.body.scrollTop),
                            ot = $(this).offset().top,
                            wh = (window.innerHeight && window.innerHeight < $(window).height()) ? window.innerHeight : $(window).height();
                    
                            return ot > st && ($(this).height() + ot) < (st + wh);
                        };
                    })( jQuery );
                    

                    我在一个叫 James 的家伙的评论 (http://remysharp.com/2009/01/26/element-in-view-event-plugin/) 中发现了这个

                    【讨论】:

                      【解决方案19】:

                      我的应用程序中有这样的方法,但它没有使用 jQuery:

                      /* Get the TOP position of a given element. */
                      function getPositionTop(element){
                          var offset = 0;
                          while(element) {
                              offset += element["offsetTop"];
                              element = element.offsetParent;
                          }
                          return offset;
                      }
                      
                      /* Is a given element is visible or not? */
                      function isElementVisible(eltId) {
                          var elt = document.getElementById(eltId);
                          if (!elt) {
                              // Element not found.
                              return false;
                          }
                          // Get the top and bottom position of the given element.
                          var posTop = getPositionTop(elt);
                          var posBottom = posTop + elt.offsetHeight;
                          // Get the top and bottom position of the *visible* part of the window.
                          var visibleTop = document.body.scrollTop;
                          var visibleBottom = visibleTop + document.documentElement.offsetHeight;
                          return ((posBottom >= visibleTop) && (posTop <= visibleBottom));
                      }
                      

                      编辑:此方法适用于 I.E. (至少版本 6)。阅读 cmets 以了解与 FF 的兼容性。

                      【讨论】:

                        【解决方案20】:

                        如果你想调整它以在另一个 div 中滚动项目,

                        function isScrolledIntoView (elem, divID) 
                        
                        {
                        
                            var docViewTop = $('#' + divID).scrollTop();
                        
                        
                            var docViewBottom = docViewTop + $('#' + divID).height();
                        
                            var elemTop = $(elem).offset().top;
                            var elemBottom = elemTop + $(elem).height();
                        
                            return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop)); 
                        }
                        

                        【讨论】:

                          【解决方案21】:

                          您可以使用 jquery 插件“onScreen”来检查滚动时元素是否在当前视口中。 插件在屏幕上显示选择器时,将选择器的“:屏幕屏幕”设置为true。 这是您可以包含在项目中的插件的链接。 "http://benpickles.github.io/onScreen/jquery.onscreen.min.js"

                          你可以试试下面这个对我有用的例子。

                          $(document).scroll(function() {
                              if($("#div2").is(':onScreen')) {
                                  console.log("Element appeared on Screen");
                                  //do all your stuffs here when element is visible.
                              }
                              else {
                                  console.log("Element not on Screen");
                                  //do all your stuffs here when element is not visible.
                              }
                          });
                          

                          HTML 代码:

                          <div id="div1" style="width: 400px; height: 1000px; padding-top: 20px; position: relative; top: 45px"></div> <br>
                          <hr /> <br>
                          <div id="div2" style="width: 400px; height: 200px"></div>
                          

                          CSS:

                          #div1 {
                              background-color: red;
                          }
                          #div2 {
                              background-color: green;
                          }
                          

                          【讨论】:

                            【解决方案22】:

                            一个基于 this answer 的示例,用于检查元素是否 75% 可见(即,不到 25% 的元素不在屏幕上)。

                            function isScrolledIntoView(el) {
                              // check for 75% visible
                              var percentVisible = 0.75;
                              var elemTop = el.getBoundingClientRect().top;
                              var elemBottom = el.getBoundingClientRect().bottom;
                              var elemHeight = el.getBoundingClientRect().height;
                              var overhang = elemHeight * (1 - percentVisible);
                            
                              var isVisible = (elemTop >= -overhang) && (elemBottom <= window.innerHeight + overhang);
                              return isVisible;
                            }
                            

                            【讨论】:

                              【解决方案23】:

                              this answer 的更高效版本:

                               /**
                               * Is element within visible region of a scrollable container
                               * @param {HTMLElement} el - element to test
                               * @returns {boolean} true if within visible region, otherwise false
                               */
                               function isScrolledIntoView(el) {
                                    var rect = el.getBoundingClientRect();
                                    return (rect.top >= 0) && (rect.bottom <= window.innerHeight);
                               }
                              

                              【讨论】:

                                【解决方案24】:

                                我为此找到的最简单的解决方案是 Intersection Observer API

                                var observer = new IntersectionObserver(function(entries) {
                                    if(entries[0].isIntersecting === true)
                                        console.log('Element has just become visible in screen');
                                }, { threshold: [0] });
                                
                                observer.observe(document.querySelector("#main-container"));
                                

                                【讨论】:

                                  【解决方案25】:

                                  修改了接受的答案,以便元素必须将其显示属性设置为“无”以外的其他值,以使质量可见。

                                  function isScrolledIntoView(elem) {
                                     var docViewTop = $(window).scrollTop();
                                    var docViewBottom = docViewTop + $(window).height();
                                  
                                    var elemTop = $(elem).offset().top;
                                    var elemBottom = elemTop + $(elem).height();
                                    var elemDisplayNotNone = $(elem).css("display") !== "none";
                                  
                                    return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop) && elemDisplayNotNone);
                                  }
                                  

                                  【讨论】:

                                    【解决方案26】:

                                    这是一种使用 Mootools 在水平、垂直或两者中实现相同目标的方法。

                                    Element.implement({
                                    inVerticalView: function (full) {
                                        if (typeOf(full) === "null") {
                                            full = true;
                                        }
                                    
                                        if (this.getStyle('display') === 'none') {
                                            return false;
                                        }
                                    
                                        // Window Size and Scroll
                                        var windowScroll = window.getScroll();
                                        var windowSize = window.getSize();
                                        // Element Size and Scroll
                                        var elementPosition = this.getPosition();
                                        var elementSize = this.getSize();
                                    
                                        // Calculation Variables
                                        var docViewTop = windowScroll.y;
                                        var docViewBottom = docViewTop + windowSize.y;
                                        var elemTop = elementPosition.y;
                                        var elemBottom = elemTop + elementSize.y;
                                    
                                        if (full) {
                                            return ((elemBottom >= docViewTop) && (elemTop <= docViewBottom)
                                                && (elemBottom <= docViewBottom) && (elemTop >= docViewTop) );
                                        } else {
                                            return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
                                        }
                                    },
                                    inHorizontalView: function(full) {
                                        if (typeOf(full) === "null") {
                                            full = true;
                                        }
                                    
                                        if (this.getStyle('display') === 'none') {
                                            return false;
                                        }
                                    
                                        // Window Size and Scroll
                                        var windowScroll = window.getScroll();
                                        var windowSize = window.getSize();
                                        // Element Size and Scroll
                                        var elementPosition = this.getPosition();
                                        var elementSize = this.getSize();
                                    
                                        // Calculation Variables
                                        var docViewLeft = windowScroll.x;
                                        var docViewRight = docViewLeft + windowSize.x;
                                        var elemLeft = elementPosition.x;
                                        var elemRight = elemLeft + elementSize.x;
                                    
                                        if (full) {
                                            return ((elemRight >= docViewLeft) && (elemLeft <= docViewRight)
                                                && (elemRight <= docViewRight) && (elemLeft >= docViewLeft) );
                                        } else {
                                            return ((elemRight <= docViewRight) && (elemLeft >= docViewLeft));
                                        }
                                    },
                                    inView: function(full) {
                                        return this.inHorizontalView(full) && this.inVerticalView(full);
                                    }});
                                    

                                    【讨论】:

                                      【解决方案27】:

                                      如果元素的任何部分在页面上可见,此方法将返回 true。它在我的情况下效果更好,可能对其他人有所帮助。

                                      function isOnScreen(element) {
                                        var elementOffsetTop = element.offset().top;
                                        var elementHeight = element.height();
                                      
                                        var screenScrollTop = $(window).scrollTop();
                                        var screenHeight = $(window).height();
                                      
                                        var scrollIsAboveElement = elementOffsetTop + elementHeight - screenScrollTop >= 0;
                                        var elementIsVisibleOnScreen = screenScrollTop + screenHeight - elementOffsetTop >= 0;
                                      
                                        return scrollIsAboveElement && elementIsVisibleOnScreen;
                                      }
                                      

                                      【讨论】:

                                        【解决方案28】:

                                        我更喜欢使用 jQuery expr

                                        jQuery.extend(jQuery.expr[':'], {  
                                            inview: function (elem) {
                                                var t = $(elem);
                                                var offset = t.offset();
                                                var win = $(window); 
                                                var winST = win.scrollTop();
                                                var elHeight = t.outerHeight(true);
                                        
                                                if ( offset.top > winST - elHeight && offset.top < winST + elHeight + win.height()) {
                                                    return true;    
                                                }    
                                                return false;  
                                            }
                                        });
                                        

                                        所以你可以这样使用它

                                        $(".my-elem:inview"); //returns only element that is in view
                                        $(".my-elem").is(":inview"); //check if element is in view
                                        $(".my-elem:inview").length; //check how many elements are in view
                                        

                                        您可以在scroll 事件函数等中轻松添加此类代码,以便在用户每次滚动视图时检查它。

                                        【讨论】:

                                          【解决方案29】:

                                          这个问题有 30 多个答案,但没有一个使用我一直在使用的极其简单的纯 JS 解决方案。没有必要仅仅为了解决这个问题而加载 jQuery,因为许多其他人都在推动。

                                          为了判断元素是否在视口内,我们必须首先确定元素在主体内的位置。我们不需要像我曾经认为的那样递归地执行此操作。相反,我们可以使用element.getBoundingClientRect()

                                          pos = elem.getBoundingClientRect().top - document.body.getBoundingClientRect().top;
                                          

                                          这个值是物体顶部和身体顶部之间的 Y 差。

                                          然后我们必须判断元素是否在视图中。大多数实现都会询问整个元素是否在视口内,因此我们将介绍这一点。

                                          首先,窗口的顶部位置是:window.scrollY

                                          我们可以通过将窗口的高度添加到它的顶部位置来获得窗口的底部位置:

                                          var window_bottom_position = window.scrollY + window.innerHeight;
                                          

                                          让我们创建一个简单的函数来获取元素的顶部位置:

                                          function getElementWindowTop(elem){
                                              return elem && typeof elem.getBoundingClientRect === 'function' ? elem.getBoundingClientRect().top - document.body.getBoundingClientRect().top : 0;
                                          }
                                          

                                          如果您使用.getBoundingClientRect() 方法向它传递的不是元素,此函数将返回元素在窗口中的顶部位置,或者返回0。这种方法已经存在了很长时间,所以您不必担心您的浏览器不支持它。

                                          现在,我们元素的顶部位置是:

                                          var element_top_position = getElementWindowTop(element);
                                          

                                          And or 元素的底部位置是:

                                          var element_bottom_position = element_top_position + element.clientHeight;
                                          

                                          现在我们可以通过检查元素的底部位置是否低于视口的顶部位置以及检查元素的顶部位置是否高于视口的底部位置来确定元素是否在视口内:

                                          if(element_bottom_position >= window.scrollY 
                                          && element_top_position <= window_bottom_position){
                                              //element is in view
                                          else
                                              //element is not in view
                                          

                                          从那里,您可以执行逻辑以在您的元素上添加或删除 in-view 类,然后您可以稍后在 CSS 中使用过渡效果进行处理。

                                          我非常惊讶我在其他任何地方都没有找到这个解决方案,但我相信这是最干净、最有效的解决方案,而且它不需要你加载 jQuery!

                                          【讨论】:

                                            【解决方案30】:

                                            可滚动div(容器)的简单修改

                                            var isScrolledIntoView = function(elem, container) {
                                                var containerHeight = $(container).height();
                                                var elemTop = $(elem).position().top;
                                                var elemBottom = elemTop + $(elem).height();
                                                return (elemBottom > 0 && elemTop < containerHeight);
                                            }
                                            

                                            注意:如果元素大于可滚动的 div,则此方法不起作用。

                                            【讨论】:

                                              猜你喜欢
                                              • 1970-01-01
                                              • 2017-01-01
                                              • 1970-01-01
                                              • 2012-07-08
                                              • 1970-01-01
                                              • 1970-01-01
                                              • 2014-04-22
                                              • 2020-08-06
                                              • 2012-04-21
                                              相关资源
                                              最近更新 更多