我正在遵循基本视差滚动效果的教程:
http://callmenick.com/2014/09/08/advanced-parallax-scrolling-effect/
这是一个很好的tute,非常容易理解和实现,但我遇到了一些代码,我只是无法完全理解。
(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;
});
};
})();
我知道它使用类视差循环遍历所有元素,获取 Yoffset 并设置背景位置。但是谁能用解释来打破这条线?
[].slice.call(parallax).forEach(function(el,i)
更新
下面有一些很好的解释,但这是否比像这样使用jQuery更好的解决方案:
$('.parallax').each(function(){
$this= $(this);
var window_y = (window.pageYOffset+1000);
var elBackgrounPos = "0 " + (window_y * speed) + "px";
$this.css('background-position', elBackgrounPos);
});
对我来说,这更具可读性,但是javascript版本在某些方面表现更好还是更有效率?
document.querySelectorAll
返回一个 NodeList,这是一种特殊的 DOM 对象。通过使用 call()
,我们可以调用 Javascript 数组的 slice()
方法将 NodeList 拆分为允许我们使用 forEach
方法的东西,这在 NodeList 上不可用。
在浏览器的 Javascript 控制台中尝试一下:
var a = document.querySelectorAll('div')
a.forEach
b = [].slice.call(a)
b.forEach
您将看到 a.forEach 将返回 undefined
b.forEach 将返回
function forEach() { [native code] }
基本上,它让我们以更简单的方式操作 NodeList 项。您还将看到 b 的 __proto__
属性是[]
,而 a 的__proto__
属性是 NodeList
。这就是为什么 b 可以调用 forEach
而 a 不能。
视差对象的类型为 NodeList,它没有 forEach 方法。
但是,使用 JavaScript 的 call((,它存在于所有对象上,我们可以暂时赋予它使用 forEach 的能力,就好像它是一个数组一样。
您甚至可以将代码缩短为[].forEach.call(parallax, function(el, i) {...})
call(( 和 apply(( 是你不熟悉它们绝对应该检查的方法