我在 HTML 页面的
<head>
部分找到了这段代码(这是一位同事制作的,但他不再在这里工作了):
(function(window, PhotoSwipe){
document.addEventListener('DOMContentLoaded', function(){
var options = {},
instance = PhotoSwipe.attach( window.document.querySelectorAll('#Gallery a'), options );
}, false);
}(window, window.Code.PhotoSwipe));
虽然我可以理解中心部分(来自 document.addEventListener),但我无法理解第一行和最后一行。他们在这里做什么?该代码来自名为 PhotoSwipe 的开源图片库。任何指针表示赞赏。
[编辑]
此代码是否与:
相同document.addEventListener('DOMContentLoaded', function(){
var options = {},
instance = window.Code.PhotoSwipe.attach( window.document.querySelectorAll('#Gallery a'), options );
}, false);
?
这是一段自动执行的受保护代码。让我们来分解一下:
(function(window, PhotoSwipe){
...
}(window, window.Code.PhotoSwipe));
括号导致我们的代码自行执行,没有任何其他东西调用它。
这将创建对
window
和 window.Code.PhotoSwipe
的引用,外部代码无法篡改这些引用。因此,在我们的括号内,PhotoSwipe
是window.Code.PhotoSwipe
的受保护别名。 window
,虽然名称没有区别,但也是对外部全局 window
对象的受保护引用。
下一行,
addEventListener
行,可以重写以将其匿名函数作为命名函数:
function myFunc() {
var options = {},
instance = PhotoSwipe.attach( window.document.querySelectorAll('#Gallery a'), options );
}
document.addEventListener('DOMContentLoaded', myFunc, false);
注意,这在功能上与原始代码中的功能相同,只是我们从
addEventListener
调用中提取了该函数并给了它一个名称。
addEventListener
附加回调函数来处理某些事件。在本例中,我们正在处理事件 DOMContentLoaded
。正在 document
对象上侦听此事件。每当听到此事件时,我们都会通过致电myFunc
做出回应。
最后一个参数,
false
,处理捕获和冒泡。这是事件在 DOM 中传播的两种方法。捕获时,事件从 DOM 顶部向内移动。当冒泡时,它们从 DOM 内部向外移动。使用 false
表示您想在 bubbling
短语中处理此问题。
在
myFunct
中,每当 DOMContentLoaded
事件发生在 document
上时都会调用该函数,我们有一行代码,它首先声明一个名为 options
的新对象。该对象是空的,没有成员。
其次,您将两个参数传递给
attach
对象的 PhotoSwipe
方法。第一个方法是选择器。它在 DOM 中搜索与 #Gallery a
匹配的元素,即具有 ID“Gallery”的元素内的任何锚元素。这意味着以下所有内容:
<div id="Gallery"><a href="#">Foo</a></div>
或者
<div id="Gallery">
<div class="picture">
<a href="#">Open</a>
</div>
<div class="picture">
<a href="#">Open</a>
</div>
</div>
这与我们创建的空对象相关联。目前尚不清楚
PhotoSwipe
内部的作用,因为此处未提供该代码。
这是一个自动执行的匿名函数。通常它用于为 Javascript 中的变量提供范围,以保持父命名空间不那么混乱(在这种情况下,父命名空间是全局命名空间。)
http://markdalgleish.com/2011/03/self-executing-anonymous-functions/
它将这些变量移动到本地范围内以使查找速度更快。它还使
window.Code.PhotoSwipe
可以用作 PhotoSwipe
。
但是,通常人们不会使用
window
作为第一个参数,而是使用 this
,因为在全局范围内执行时,它保证是浏览器中的全局对象(即 window
)。
第一行是函数声明。 最后一个是使用参数自动调用此函数。这样,函数就可以一步声明、调用并运行。
重新格式化:
(function(window, PhotoSwipe){
document.addEventListener('DOMContentLoaded', function(){
var options = {},
instance = PhotoSwipe.attach( window.document.querySelectorAll('#Gallery a'),
options );
}, false);
}(window, window.Code.PhotoSwipe));
这将创建一个带有两个参数(window 和 PhotoSwipe)的函数,该函数添加一个事件侦听器 - 第二个(内部)函数 - 然后立即使用值 window 和 window.Code.PhotoSwipe 作为参数调用外部函数。
为什么要这样做? Javascript 不擅长分隔作用域,除非您将代码放入函数中。所以示例中的 main 函数内部,PhotoSwipe 只能引用传入的第二个参数。