2011-06-09 48 views
0

在下面的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未定義。爲什麼當我在代碼的開頭聲明它併爲它分配一個元素時它是未定義的?

回答

3

您指的是el,就像它是一個全局變量。你需要說this.el

+1

保羅,你的答案只有在函數以特定的,奇怪的方式被調用時纔有效。如果它是'animated.el.onclick = function(){animated.doAnimation()};'那麼你是對的。但是,在'doAnimation'函數內'animated.el.onclick = animated.doAnimation'更常見也可能更好的實踐案例中,'this'將引用DOM元素,而不是'animated'對象, this.el'未定義。 – ErikE 2011-06-09 17:22:52

-1

執行以下操作以適當參考EL之一:

  1. alert(typeof this.el);
  2. alert(typeof animated.el);
+0

Kon,你的答案#1只適用於以特殊的怪異方式調用函數。如果它是'animated.el.onclick = function(){animated.doAnimation()};'那麼你是對的。但是,在'doAnimation'函數內'animated.el.onclick = animated.doAnimation'更常見也可能更好的實踐案例中,'this'將引用DOM元素,而不是'animated'對象, this.el'未定義。此外,#2將起作用,但您的觀點都不能解決正在創建的不需要的關閉。 – ErikE 2011-06-09 17:24:42

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重要的是,它會永遠動態確定在運行時間功能,並且在函數聲明的時間從來沒有意義。

只是爲了清楚起見,這裏的,如果你沒有通過閉合做函數的外觀:

(函數(){VAR EL =的document.getElementById( 「divNavyBox」) el.onclick =功能(){ el.className = el.className ==='box'?'boxAlt':'box'; }; }());

正如我所說,這將創建一個封閉的外部匿名函數,保持el實例化並持有對div的引用。由於div本身具有內部函數的引用(這本身就是保持閉包打開的東西),所以瀏覽器在解決此通告時可能會遇到問題。這是由於在瀏覽器引擎中處理的瀏覽器的DOM對象與在單獨的javascript引擎中處理的JavaScript對象之間的分離,從而防止任何一個人檢測到引用是循環的並且可以對垃圾收集對象。 (有些瀏覽器可能已經解決了這個問題,但不是全部,我知道至少IE6有這個問題)。

如果您對事件功能需要在別處進行命名或引用的原因有進一步的說明,請發表評論,我會相應更新。

+0

@Michael請注意我更新了我的答案,並且您可能需要考慮一些問題。 – ErikE 2011-06-09 17:21:02

相關問題