106

Function to check if the div class "media" is within the browsers visual viewport regardless of the window scroll position.

<HTML>
<HEAD>
  <TITLE>My first HTML document</TITLE>
</HEAD>
<BODY>
  <div class="main">
   <div class="media"></div>
  </div>

</BODY>
</HTML>

Trying to use this plugin https://github.com/customd/jquery-visible with this function but I don't know how to make it work.

$('#element').visible( true );
Erenor Paz
  • 2,641
  • 3
  • 34
  • 41
Vim Bonsu
  • 1,500
  • 6
  • 18
  • 25

5 Answers5

116

Check if element is visible in viewport using jquery:

First determine the top and bottom positions of the element. Then determine the position of the viewport's bottom (relative to the top of your page) by adding the scroll position to the viewport height.

If the bottom position of the viewport is greater than the element's top position AND the top position of the viewport is less than the element's bottom position, the element is in the viewport (at least partially). In simpler terms, when any part of the element is between the top and bottom bounds of your viewport, the element is visible on your screen.

Now you can write an if/else statement, where the if statement only runs when the above condition is met.

The code below executes what was explained above:

// this function runs every time you are scrolling

$(window).scroll(function() {
    var top_of_element = $("#element").offset().top;
    var bottom_of_element = $("#element").offset().top + $("#element").outerHeight();
    var bottom_of_screen = $(window).scrollTop() + $(window).innerHeight();
    var top_of_screen = $(window).scrollTop();

    if ((bottom_of_screen > top_of_element) && (top_of_screen < bottom_of_element)){
        // the element is visible, do something
    } else {
        // the element is not visible, do something else
    }
});

This answer is a summary of what Chris Bier and Andy were discussing below. I hope it helps anyone else who comes across this question while doing research like I did. I also used an answer to the following question to formulate my answer: Show Div when scroll position.

codeAndStuff
  • 427
  • 3
  • 14
ADB
  • 1,202
  • 1
  • 7
  • 11
  • I think it should be $("#element").outerHeight(); – boblapointe Apr 10 '16 at 18:42
  • 4
    little correction; like @boblapointe points out: it should be outerheight(), and a dot ('.') is missing between offset()top – Maurice Jun 10 '16 at 10:25
  • 2
    Without plugin?! what about: $(window).scroll?? – Bruno Casali Oct 13 '16 at 14:34
  • Are you referring to jquery? – VeeK Dec 07 '16 at 10:41
  • A [previous version](http://stackoverflow.com/revisions/33979503/4) of this answer may also be helpful if you want to detect when an element first enters view/is fully in view, and then when it begins to leave view (when the top of the next element is visible). – ADB May 20 '17 at 00:01
  • @ADB This works great for id's but not classes. Is there a way to get that working? – Rob Aug 03 '17 at 14:22
  • Killer solution to handle simple cases without the need for an additional plugin. – jyoseph Oct 20 '17 at 15:46
  • This is the right way to do it. Thanks. – Andy Sep 12 '19 at 00:45
  • And what about the vertical boundaries of the viewport? With sliders/carousels an element that is inside the horizontal boundaries of the viewport could still be outside of the vertical ones. – Krzysztof Wołowski May 11 '20 at 16:57
  • Way to complicated. You should just have to call a method where you put in the element and it gives you back if it is visible or not. – Black Dec 09 '20 at 12:48
112

You can write a jQuery function like this to determine if an element is in the viewport.

Include this somewhere after jQuery is included:

$.fn.isInViewport = function() {
    var elementTop = $(this).offset().top;
    var elementBottom = elementTop + $(this).outerHeight();

    var viewportTop = $(window).scrollTop();
    var viewportBottom = viewportTop + $(window).height();

    return elementBottom > viewportTop && elementTop < viewportBottom;
};

Sample usage:

$(window).on('resize scroll', function() {
    if ($('#Something').isInViewport()) {
        // do something
    } else {
        // do something else
    }
});

Note that this only checks the top and bottom positions of elements, it doesn't check if an element is outside of the viewport horizontally.

Tom Pažourek
  • 7,390
  • 7
  • 51
  • 92
  • 2
    If checking within a div (not the window) then remember to subtract the parent divs offset. – Karlth Feb 26 '17 at 16:42
  • you would subtract offset like this if your button is on top and element appears on the bottom: `return ( elementBottom > viewportTop ) && ( elementTop < viewportBottom - $( this ).height() );` – Arthur Tarasov Jul 29 '17 at 10:31
  • 1
    Thanks! I made a more complete plugin using your code as base: https://github.com/frontid/jQueryIsInViewport – Capy Aug 14 '17 at 16:59
  • `$(window).height()` doesn't factor in a mobile device's zoom (at least when using jQuery v1.9). A better solution is to use `window.innerHeight`, which does change when pinching the screen to zoom in on a mobile device. – Steven Apr 11 '18 at 20:14
  • btw this doesn't work if you are using Chrome debugger in mobile mode and click on the page and scroll. Only works if I use the trackwheel to scroll up and down. Unless I am missing something – Si8 Aug 22 '18 at 13:21
  • This solution does not work if the element is not in the viewport because it is too far right or left – Black Dec 09 '20 at 12:51
  • @Black Yes, it's written in the answer, please see the last sentence. – Tom Pažourek Dec 09 '20 at 14:09
63

According to the documentation for that plugin, .visible() returns a boolean indicating if the element is visible. So you'd use it like this:

if ($('#element').visible(true)) {
    // The element is visible, do something
} else {
    // The element is NOT visible, do something else
}
Black
  • 12,789
  • 26
  • 116
  • 196
David
  • 176,566
  • 33
  • 178
  • 245
  • 11
    you should remove the (true) in visible() – slvnperron Dec 26 '13 at 21:24
  • 1
    @slvnperron: Why? It's a valid use of the plugin, and corresponds to the original code posted in the question. – David Dec 26 '13 at 21:25
  • well he probably want to check for the entire div visibility, the argument is for partial detection – slvnperron Dec 26 '13 at 21:32
  • 2
    @slvnperron: True : the entire element is visible, false : part of the element is visible – ThunderPhoenix Dec 26 '13 at 21:39
  • @David So this code works okay BUT here is the site I'm working on dev1.envisionwebdesign.co/johnreid/campaign.html. The site is a one page html with 16 sections. The first section does not have the navigation and text block on the left. All others do. What I need is when you scroll to each section, the navigation and text block slide in (They are contained in the same div element "media-nav"). I'm using this plugin for the transition effect link. – – Vim Bonsu Dec 26 '13 at 21:59
  • @David The problem is the transition happens immediately after the site loads and not when the element is "in-view". Each section is contained in a div with class like so (.page1, .page2, .page3 ....). the div class "media-nav" is contained in each of the above divs. What I need is, when a div like ".page2" is in view, it's ".media-nav" transitions in – – Vim Bonsu Dec 26 '13 at 21:59
  • @David May be you can suggest something for my [problem here](http://stackoverflow.com/questions/29517645/jquery-visible-plugin-using-element-visibletrue-but-still-returns-true-on)? – Solace Apr 08 '15 at 17:40
  • @David link is broken. – Michael Okoli Dec 04 '17 at 11:45
  • 2
    A nice little library. Unfortunately, it's abandoned and no longer works with current versions of jQuery. It throws errors like `Uncaught TypeError: r.getClientRects is not a function`, which is common of libraries incompatible with jQuery>3. – Cerin Nov 20 '20 at 17:41
-1

You can see this example.

// Is this element visible onscreen?
var visible = $(#element).visible( detectPartial );

detectPartial :

  • True : the entire element is visible
  • false : part of the element is visible

visible is boolean variable which indicates if the element is visible or not.

ThunderPhoenix
  • 1,534
  • 4
  • 18
  • 43
-2
var visible = $(".media").visible();
slvnperron
  • 1,291
  • 10
  • 13