在下面的javascript代码中,我希望元素el指向ID为“divNavyBox”的div。这是divNavyBox的代码:
<div id="divNavyBox" class="box" onmouseover="animated.doAnimation()"></div>
以下代码是使用的javascript。请注意,会弹出一个警报,其中包含有关el类型的信息。
var animated = {
el : document.getElementById("divNavyBox"),
doAnimation : function() {
alert(typeof el);
if (el.className=="box") {
alert("2");
el.className="boxAlt";
}
if (el.className=="boxAlt") {
el.className="box";
}
}
};
每次弹出警报时,都会说el未定义。当我在代码的开头声明它并为它分配一个元素时,为什么它是未定义的?
答案 0 :(得分:3)
你指的是el
,因为它是一个全局变量。你需要说this.el
答案 1 :(得分:0)
对象没有范围,只有函数。您期望从对象中取消引用el
但是当函数实际运行时,它没有el
来引用:函数局部变量el
尚未设置为任何值,也没有全局变量el
。如果你想在你的函数中只使用el
,你可以使外容器成为一个函数,并将el
更改为它的局部变量,或使el
全局,或参考animated.el
。
但是,由于该函数仅涉及单个元素,为什么还要为函数命名呢?为什么它不属于divNavyBox
的事件?请解释您如何调用该功能和/或将其绑定到某个事件,以便我们为您提供更清晰的信息。
还有一个问题:重要的是不要对DOM元素进行闭包,或者在脚本的任何地方保持对它们的引用,因为这会导致内存泄漏。这意味着您不仅应该使用this
来引用函数内部单击的div,还应该完全消除el
变量,这样就不会引用该元素。我就是这样做的:
document.getElementById("divNavyBox").onclick = function() {
alert(typeof this);
if (this.className === "box") {
alert("2");
this.className = "boxAlt";
} else if (this.className === "boxAlt") {
this.className = "box";
}
// or alternately, removing the alerts, the whole function could be:
this.className = this.className === 'box' ? 'boxAlt' : 'box';
};
关键字this
始终指的是在运行时与每个javascript函数配对的特殊对象。对于DOM元素上的事件,this
将引用元素本身。关于this
要记住的重要一点是它将始终在函数运行时动态确定,并且在函数声明时间内永远不会有意义。
为了清楚起见,如果你通过闭包来做这件事,那么这个函数的外观如下:
(function(){ var el = document.getElementById(“divNavyBox”) el.onclick = function(){ el.className = el.className ==='box'? 'boxAlt':'box'; }; }());
正如我所说,这将在外部匿名函数上创建一个闭包,保持el
实例化并保持对div的引用。由于div本身有一个返回内部函数的引用(它本身就是保持闭包打开的东西),浏览器在解决这个循环时会遇到问题。这是由于在浏览器引擎中处理的浏览器DOM对象与在单独的javascript引擎中处理的javascript对象之间的分离,阻止任何一个检测到引用是循环的并且对象可以被垃圾收集。 (有些浏览器可能已经解决了这个问题,但并非全部解决了这个问题,而且我知道至少IE6存在这个问题。)
如果您有关于为何需要在其他地方命名或引用事件功能的进一步说明,请发表评论,我会相应更新。
答案 2 :(得分:-1)
执行以下操作之一以正确引用el:
alert(typeof this.el);
alert(typeof animated.el);