Search code examples
javascriptjqueryparallax

jQuery / Javascript Parallax Code - explanation


I am following a tutorial for a basic parallax scrolling effect:

http://callmenick.com/2014/09/08/advanced-parallax-scrolling-effect/

It is a good tute and pretty easy to understand and implement but I came across some code I just can't quite get my head around.

(function(){

  var parallax = document.querySelectorAll(".parallax"),
      speed = 0.5;

  window.onscroll = function(){
    [].slice.call(parallax).forEach(function(el,i){

      var windowYOffset = window.pageYOffset,
          elBackgrounPos = "50% " + (windowYOffset * speed) + "px";

      el.style.backgroundPosition = elBackgrounPos;

    });
  };

})();

I get that it loops through all elements with the class parallax, gets the Yoffset and sets the background position. But can anyone breakdown this line with an explanation?

[].slice.call(parallax).forEach(function(el,i)

UPDATE

Some great explanations below but is this a better solution than using jQuery like so:

$('.parallax').each(function(){
        $this= $(this);
        var window_y = (window.pageYOffset+1000);
        var elBackgrounPos = "0 " + (window_y * speed) + "px";  
        $this.css('background-position', elBackgrounPos);
});

To me this is much more readable, but does the javascript version perform better or is more efficient in some ways?


Solution

  • document.querySelectorAll returns a NodeList, which is a special kind of DOM object. By using call(), we can invoke the slice() method of Javascript arrays to split the NodeList into something that allows us to then use the forEach method, which is not available on NodeLists.

    Try this out in the Javascript console of your browser:

    var a = document.querySelectorAll('div')
    a.forEach
    
    b = [].slice.call(a)
    b.forEach
    

    You'll see that a.forEach will return undefined and b.forEach will return

    function forEach() { [native code] }

    Basically it lets us manipulate the NodeList items in an easier way. You'll also see that the __proto__ property of b is [] while the __proto__ property of a is NodeList. This is why b can call forEach and a cannot.