21

So I am trying to call some functions when fullscreen sections are in the viewport. Let's say I have 7 sections, then I want something to happen when a certain section is inside the viewport (I have a function that snaps the sections into the viewport so there can never be multiple sections in the viewport, but I am trying to find out which section is visible in the viewport).

Here is a fiddle: http://jsfiddle.net/h7Hb7/2/

function isInViewport() {
    $("section").each(function () {
        var $this = $(this),
            wHeight = $(window).height(),
            rect = $this.getBoundingClientRect(); // Error in console

        // Borrowed from http://stackoverflow.com/a/7557433/5628
        if (rect.top >= 0 && rect.bottom <= wHeight) {
            console.log($this.attr("id") + "in viewport");
        }
    });
}

$(window).scroll(function () {
    // Other functions are called inside the setTimeout function, can't remove
    clearTimeout($.data(this, "scrollTimer"));
    $.data(this, "scrollTimer", setTimeout(function () {
        isInViewport();
    }, 1200));
});

I don't know where to start looking but I am guessing it's to do with the each function. Is it the each function that poses a problem? It can't be a CSS issue, because the problem occurs on scroll when the CSS has already loaded.

Bram Vanroy
  • 22,919
  • 16
  • 101
  • 195

2 Answers2

28

You could stick with jQuery and use the array [] notation ie:

var myClient = $(currentGrid)[0].getBoundingClientRect();
alert(myClient.top)
josliber
  • 41,865
  • 12
  • 88
  • 126
mustbebuilt
  • 389
  • 4
  • 2
26

jQuery object doesn't have getBoundingClientRect method, you should get the HTMLElement object and then call the method or:

this.getBoundingClientRect();

As a suggestion, if using a plugin is an option, you can consider using the jquery.inview plugin.

undefined
  • 136,817
  • 15
  • 158
  • 186
  • Ah, silly me. jQuery is a very easy to use library, but sometimes it makes you overlook to things that are right under your nose! I think that a plugin would be overkill though, do you think it has any more to offer than my small snippet? – Bram Vanroy Aug 04 '14 at 13:09
  • I take that back, apparently it seems like it can do a lot! I especially like how you can unbind and use it in combination with `one()`. Thanks for the tip! – Bram Vanroy Aug 04 '14 at 13:11
  • `this.getBoundingClientRect()` isn't working inside a for with plain Javascript either. – thednp Apr 21 '15 at 21:17
  • 2
    @thednp Nothing prevents the `getBoundingClientRect` method from working in a `for` loop. – undefined Apr 21 '15 at 22:31
  • @Vohuman yes, I figured later, I was trying to get `getBoundingClientRect` for index values and not actual items. My bad – thednp Apr 21 '15 at 22:35
  • Within a jQuery scroll event (without any loops), this solution worked splendidly when I used `var el = document.querySelector('#element'); var position = el.getBoundingClientRect();`. Posting in case someone else comes across this with a similar but not idential issue the OP had. – mckenna May 03 '19 at 14:55