MP_Webby
MP_Webby

Reputation: 916

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?

Upvotes: 1

Views: 565

Answers (2)

Khalah Jones - Golden
Khalah Jones - Golden

Reputation: 317

The parallax object is of the type NodeList, which doesn't have a forEach method.

However using JavaScript's call(), which exists on all objects, we can temporarily give it the ability to use forEach as if it were an array.

you could even shorten the code to be just [].forEach.call(parallax, function(el, i) {...})

call(), and apply() are methods you should definitely check out if you're not familiar with them

Upvotes: 1

Aweary
Aweary

Reputation: 2312

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.

Upvotes: 2

Related Questions