2012-04-27 57 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