使用jQuery检查div是否在视口内可见

8

我想使用jQuery来检查红色Div是否在视口中,如果不是,则检查橙色Div是否在视口中。我使用的函数在只有一个IF语句时有效,但当我添加另一个IF ELSE语句时,它无法正常工作。

以下是该函数:

$.fn.isOnScreen = 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));

};

以下是我添加的代码,用于检查并查看视口中是否有红色div或橙色div:

$(window).scroll(function() {
    if ($('.red').isOnScreen() === true) { 
       $('.red').remove();
    } else if ($('.orange').isOnScreen() === true) {
       $('.orange').remove();   

    }
});

here is a jfiddle http://jsfiddle.net/wN7ah/453/


为什么不使用他们网站上提供的这个:http://jsfiddle.net/moagrius/wN7ah/? - Ani
我希望它在用户滚动而不是点击时检查哪个div在屏幕上。 - Die 20
你在哪里提到了点击功能?你正在窗口滚动时执行它...你想要在点击上执行吗? - Ani
我想在滚动时检查,而不是在点击时。 - Die 20
这就是我所做的...检查答案。 - Ani
由于这是我搜索结果中的最佳答案,因此我添加了一个现代化的回答。 - tobiv
3个回答

19

这里是可使用的版本:http://jsfiddle.net/wN7ah/455/

实现奇迹的功能:

$.fn.isOnScreen = 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));

};

使用方法:

$(window).scroll(function() {
   if ($('.orange').isOnScreen() == true) {
     //alert("removing orange");
     $('.orange').remove();   
   }
  if ($('.red').isOnScreen() == true) { 
    //alert("removing red");
    $('.red').remove();
   } 

});

如果屏幕上有任何橙色或红色,它将把它们移除。

如果您想要检查何时被移除,请在移除之前添加警报:http://jsfiddle.net/wN7ah/457/


4
请考虑在答案中添加“isOnScreen”扩展,而不是jsfiddle。谢谢。 - Hatem Alimam

2
我们可以用纯JavaScript函数来实现,如下所示:

function elementInViewport2(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 + window.innerHeight) &&
    left < (window.pageXOffset + window.innerWidth) &&
    (top + height) > window.pageYOffset &&
    (left + width) > window.pageXOffset
  );
}
ele = document.getElementById('visb_true');
console.log("visible: ", elementInViewport2(ele))
ele = document.getElementById('visb_false');
console.log("visible: ", elementInViewport2(ele))
#visb_true{
    color: green;
    font-weight: 800;
}

#visb_false{
    color: red;
    font-weight: 800;
}
<html>
<body>
<p> hello </p>
<p> hello </p>
<p id="visb_true"> hello </p>
<p> hello </p>
<p> hello </p>
<p> hello </p>
<p> hello </p>
<p> hello </p>
<p> hello </p>
<p> hello </p>
<p> hello </p>
<p> hello </p>
<p> hello </p>
<p> hello </p>
<p> hello </p>
<p> hello </p>
<p> hello </p>
<p> hello </p>
<p> hello </p>
<p> hello </p>
<p> hello </p>
<p> hello </p>
<p> hello </p>
<p> hello </p>
<p> hello </p>
<p> hello </p>
<p> hello </p>
<p> hello </p>
<p> hello </p>
<p> hello </p>
<p> hello </p><p> hello </p>
<p id="visb_false"> hello </p>
<p> hello </p>
</body>
</html>


JavaScript 的解决方案真是救命稻草,谢谢! - Nicholas Barrow

0

现代的做法是使用Intersection Observer API。这是一份优秀的文档,以下基本上只是其中的摘录。它适用于所有现代浏览器。

首先,创建一个Intersection Observer:

let options = {
    root: document.querySelector('#scrollArea'), // null for entire viewport 
    rootMargin: '0px',
    threshold: 1.0
}
let observer = new IntersectionObserver(callback, options);

然后选择要监视的一个或多个元素:

let target = document.querySelector('#watchItem');
observer.observe(target);

最后是回调函数。它接收一个包含所有被观察项目的列表entries。通过检查isIntersecting属性的值,可以判断该项是否表示当前与根元素相交的元素。
let callback = (entries, observer) => {
    entries.forEach(entry => {
        if(entry.isIntersecting) {
            // Do your thing
        }
    });
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接