Die 20
Die 20

Reputation: 261

Checking if a div is visible within viewport using jquery

I am trying to use jquery to check if Div RED is within the viewport, and if not, then check if Div ORANGE is in the viewport. The function I am using works great if there is only one IF statement, but when I add another IF ELSE statement, it wont work.

here is the function:

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

};

here is the code I added to check and see if div red or div orange is within the viewport

$(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/

Upvotes: 8

Views: 23997

Answers (3)

tobiv
tobiv

Reputation: 842

The modern way to do this is by using the Intersection Observer API. This is an excellent documentation, the following are basically just excerpts from it. It works with all modern browsers.

First, create an Intersection Observer:

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

Then target an element (or multiple elements) to watch:

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

Lastly, the callback. It receives a list of all watched items entries. Check the value of the isIntersecting property to see if the entry represents an element that currently intersects with the root.

let callback = (entries, observer) => {
    entries.forEach(entry => {
        if(entry.isIntersecting) {
            // Do your thing
        }
    });
};

Upvotes: 0

anjaneyulubatta505
anjaneyulubatta505

Reputation: 11665

We can do it with pure javascript function like below

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>

Upvotes: 2

Ani
Ani

Reputation: 4523

Here is the working versions: http://jsfiddle.net/wN7ah/455/

Function that does the magic:

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

};

Usage:

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

});

If any orange or red is present in onscreen it'll remove them.

If you want to check when it's removed, add alert before removing: http://jsfiddle.net/wN7ah/457/

Upvotes: 21

Related Questions