如何使用jquery检查一个元素是否在用户视图中

How to check if an element is in the view of the user with jquery

本文关键字:是否 元素 用户 视图 一个 jquery 何使用 检查      更新时间:2023-09-26

我有一个非常大的可拖动的div在我的窗口。这个div有一个较小的窗口

<div id="draggable-area" style="width:500px;height:500px;overflow:hidden">
 <div id="draggable" style="width:5000px;height:5000px">
     <ul>
         <li></li>
         <li></li>
         <li></li>
         <li></li>
         <li></li>
         ....
     </ul>
  </div>
</div>  

我怎么知道如果li元素在用户视图中可见(我的意思是真正可见,而不是在溢出区域)?

检查一个元素是否在当前viewport中:

function elementInViewport(el) {
  var top = el.offsetTop;
  var left = el.offsetLeft;
  var width = el.offsetWidth;
  var height = el.offsetHeight;
  while(el.offsetParent) {
    el = el.offsetParent;
    top += el.offsetTop;
    left += el.offsetLeft;
  }
  return (
    top >= window.pageYOffset &&
    left >= window.pageXOffset &&
    (top + height) <= (window.pageYOffset + window.innerHeight) &&
    (left + width) <= (window.pageXOffset + window.innerWidth)
  );
}

(源)对于一个更健壮的方法,我推荐Viewport selector,它允许你只做:

$("#elem:in-viewport")

看看这个插件

它给你一个选项来执行以下选择器

$(":in-viewport")
$(":below-the-fold")
$(":above-the-top")
$(":left-of-screen")
$(":right-of-screen")

https://github.com/sakabako/scrollMonitor

var scrollMonitor = require("./scrollMonitor"); // if you're not using require, you can use the scrollMonitor global.
var myElement = document.getElementById("itemToWatch");
var elementWatcher = scrollMonitor.create( myElement );
elementWatcher.enterViewport(function() {
    console.log( 'I have entered the viewport' );
});
elementWatcher.exitViewport(function() {
    console.log( 'I have left the viewport' );
});
elementWatcher.isInViewport - true if any part of the element is visible, false if not.
elementWatcher.isFullyInViewport - true if the entire element is visible [1].
elementWatcher.isAboveViewport - true if any part of the element is above the viewport.
elementWatcher.isBelowViewport - true if any part of the element is below the viewport.

使用getBoundingClientRect():

var isInViewport = function (elem) {
    var bounding = elem.getBoundingClientRect();
    return (
        bounding.top >= 0 &&
        bounding.left >= 0 &&
        bounding.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
        bounding.right <= (window.innerWidth || document.documentElement.clientWidth)
    );
};

如果元素完全在视口中则返回true,否则返回false。

var myElem = document.querySelector('#draggable');
if (isInViewport(myElem)) {
    // Do something...
}

完整的解释在这里找到

我的解决方案是使用给定的代码示例,它将向您展示如何确定li元素是否可见的总体思路。查看jsFiddle,其中包含您的问题中的代码。

jQuery .offset()方法允许我们检索元素相对于文档的当前位置。如果您单击可拖动元素中的一个li元素,那么您与顶部的偏移量将在0到500之间,与左侧的偏移量将在0到500之间。如果您调用当前不可见的项的offset函数,则从顶部或左侧的偏移量将小于0或大于500。

如果这不是一个艰巨的任务,我总是喜欢从' scratch '中编写我需要的代码,它在必须修改或调试时给了我更多的灵活性,因此我建议使用jQuery的偏移函数而不是使用插件。如果您想要完成的任务相当简单,那么使用您自己的函数可以减少一个需要加载的库。

我使用(检查一个元素是否至少部分在视图中)以下代码:

var winSize;
function getWindowSize() {
            var winW,WinH = 0;
            if (document.body && document.body.offsetWidth) {
                winW = document.body.offsetWidth;
                winH = document.body.offsetHeight;
            }
            if (document.compatMode == 'CSS1Compat' &&
                document.documentElement &&
                document.documentElement.offsetWidth) {
                winW = document.documentElement.offsetWidth;
                winH = document.documentElement.offsetHeight;
            }
            if (window.innerWidth && window.innerHeight) {
                winW = window.innerWidth;
                winH = window.innerHeight;
            }
            return {w:winW, h:winH};
        }
winSize = getWindowSize();    
function inView(element) {
                var box = element.getBoundingClientRect();
                if ((box.bottom < 0) || (box.top > winSize.h)){
                    return false;
                }
                return true;
            }