2012-04-27 67 views
4

我不使用eval,我不確定Crockford在以下方面遇到了什麼問題。有沒有更好的方法來解決以下問題,或者這只是我需要忽略的一點(如果有需要改進的地方,我更喜歡完善/改進我的解決方案)。函數(..)拋出'eval是邪惡的'消息

我正在使用一些像素跟蹤的東西,在這種情況下,客戶端已綁定JS功能到onclick屬性的HTML圖像標記重定向站點。我需要可靠地跟蹤咔嗒聲,而不會遇到圖像上具有多個事件偵聽器的競態條件。策略是在運行時重寫事件,並在我自己的函數中複製和運行它。請注意,這是應用於我無法控制且無法更改的網站。所以解決方案看起來像這樣:

... 
func = Function(img.attr('onclick')); 
... 
img.attr('onclick', ''); 
... //some custom tracking code 
func.call(this); 

和JSLint檢查器拋出eval is evil錯誤。

有沒有更好的方法來避免href動作的多個事件的競賽條件?

+0

好像你裏面只需要觸發onclick事件處理程序,如果它包含JavaScript代碼。 img.onclick();或img.onclick.call(); – GillesC 2012-04-27 17:15:15

+0

@gillesc技術上說,這是一個_property_而不是_attribute_。 – Alnitak 2012-04-27 17:18:58

+0

事實上,但感謝指出它不是一個屬性,所以我可以正確糾正它。 – GillesC 2012-04-27 17:20:42

回答

7

你使用隱式,因爲eval你要求的回調函數因爲它被指定爲HTML作爲字符串的屬性,然後構建與它Function

只需使用img.onclick財產相反,你將直接獲得該功能的瀏覽器從屬性構建,然後就可以.call

var func = img.onclick; // access already compiled function 
img.onclick = null;  // property change updates the attribute too 

... // some custom tracking code 

func.call(img, ev);  // call the original function 

或更好:

(function(el) { 
    var old = el.onclick; 
    el.onclick = function() { 
     // do my stuff 
     .. 
     // invoke the old handler with the same parameters 
     old.apply(this, arguments); 
    } 
})(img); 

後一種方法的優點有兩點:

  1. 它不產生新的全局變量 - 一切都隱藏在匿名閉包
  2. 它確保原處理函數被調用具有完全相同的參數提供給您的替換功能
+0

我在複製之後剝離了'onclick',因此它不再是圖像的屬性。請注意,我提到我稍後會在自己的代碼中調用該函數。如果我將其留在那裏,我無法保證我的跟蹤代碼在重定向將其切斷之前完成 – patrickgamer 2012-04-27 17:23:25

+1

@patrickgamer因此複製其(函數引用)屬性值,而不是原始屬性文本。 – Alnitak 2012-04-27 17:27:15

+0

我一直在你和Phrogz之間來回彈跳。我從來沒有真正考慮過將屬性複製爲函數和複製元素的屬性之間的區別。非常感謝。 – patrickgamer 2012-04-27 18:32:51

2
var oldClick = myImg.onclick; 
myImg.onclick = function(evt){ 
    // Put you own code here 
    return oldClick.call(this, evt); 
}; 
+0

啊,我明白你現在說的話。這不會再拋出JSLint錯誤嗎? – patrickgamer 2012-04-27 17:36:33

+0

TIAS你自己:) – Phrogz 2012-04-27 17:38:31