0

I am creating a new site that contains multiple sections. Each section has a header that contains an 1 heading (h1). Also each section has an id attribute.

What I am looking for is how I can add a minimal parallax effect to the headers for each section. When the section is in the viewport, it should start with animate the margin-top of the header for like an x amount of pixels, like 5 or 10px.

I would like to check which section is in the viewport of the browser, and if so, begin the parallax animation. If it is possible, without any plugin. How should I do this?

I came up with the following:

$(window).scroll(function() {

    // Get the offset of the window from the top of page
    var windowPos = $(window).scrollTop();

    $('.main').find('section').each(function() { 
        var anchorId = $(this);
        var target = $(anchorId.attr("id"));
        var offsetTop = target.position().top;

        if (offsetTop <= windowPos && offsetTop + target.height() > windowPos) {
            console.log(this);
            // Parallax function here
        }

    });


});

Unfortunately, I receive the error: Uncaught TypeError: Cannot read property 'top' of undefined.

So, I would like that the code is returning the id of the section, that is then in the viewport visible. And start then the animation the header for that section.

Thank you in advance. Live demo here: http://codepen.io/anon/pen/xZwpzX?editors=101

Caspert
  • 4,271
  • 15
  • 59
  • 104
  • 1
    So `$(anchorId.attr("id"))` returns empty object. But because IDs must be unique on document context and because you didn't provide any relevant MCVE (or at least HTML markup), how can we help?! – A. Wolff Dec 13 '15 at 14:23

2 Answers2

1

Your this statement:

var target = $(anchorId.attr("id"));
var offsetTop = target.position().top;

should be:

var target = $("#"+anchorId.attr("id"));
var offsetTop = target.offset().top;

As anchorId.attr('id') will return the id which is string therefore you need to prepend # for id or . for class. Also, You have element in thisyou may use it.

Ajay Narain Mathur
  • 5,326
  • 2
  • 20
  • 32
0

Try this, hope this will work:

function isElementInViewport (el) {

    //special bonus for those using jQuery
    if (typeof jQuery === "function" && el instanceof jQuery) {
        el = el[0];
    }

    var rect = el.getBoundingClientRect();

    return (
        rect.top >= 0 &&
        rect.left >= 0 &&
        rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
        rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
    );

}

$(window).scroll(function() {

    $('.main').find('section').each(function() { 

        if (isElementInViewport($(this))) {
            console.log($(this));
            // Parallax function here
        }

    });

})

How to tell if a DOM element is visible in the current viewport?

Community
  • 1
  • 1
Shishir Morshed
  • 797
  • 8
  • 21