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?
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.