JavaScript:添加onClick处理程序而不覆盖现有处理程序

我正在尝试修改页面上的所有链接,以便在单击它们时执行一些额外的工作。

一个简单的方法可能是这样的:

function adaptLinks() { var links = document.getElementsByTagName('a'); for(i = 0; i != links.length; i++) { links[i].onclick = function (e) {  return true; } } } 

但是一些链接已经有一个应该保留的onClick处理程序。 我尝试了以下方法:

 function adaptLinks() { var links = document.getElementsByTagName('a'); for(i = 0; i != links.length; i++) { var oldOnClick = links[i].onclick; links[i].onclick = function (e) { if(oldOnClick != null && !oldOnClick()) { return false; }  return true; } } } 

但这不起作用,因为oldOnClick仅在调用处理程序时进行评估(它包含最后一个链接的值作为此点)。

您需要创建一个闭包以保留每个链接的原始onclick值:

 Hi There  

请注意,如果原始onclick处理程序返回true,则此实现仅执行新的onclick处理。 如果这是你想要的,那很好,但请记住,如果你想要执行新的onclick处理,即使原始处理程序返回false,你也必须稍微修改代码。

更多关于comp.lang.javascript FAQ和Douglas Crockford的闭包。

不要直接分配给事件处理程序:使用subscribe model addEventListener / attachEvent (它也有删除对!)。

这里介绍好。

使用addEventListener (支持浏览器的DOM)或attachEvent (IE)的包装器。

请注意,如果您希望在不覆盖旧值的情况下将值存储在变量中,则可以使用闭包 。

 function chain(oldFunc, newFunc) { if (oldFunc) { return function() { oldFunc.call(this, arguments); newFunc.call(this, arguments); } } else { return newFunc; } } obj.method = chain(obj.method, newMethod); 

在面向方面编程中 ,这被称为“ 建议 ”。

如何设置oldClick = links[i].onclick or an empty function 。 像这样

 var oldOnClick = links[i].onclick || function() { return true; }; links[i].onclick = function (e) { if (!oldOnClick()) return false; // return true; } 

或者您可以像其他人推荐的那样使用attachEventaddEventListener

 function addEvent(obj, type, fn) { if (obj.addEventListener) obj.addEventListener(type, fn, false); else if (obj.attachEvent) obj.attachEvent('on' + type, function() { return fn.apply(obj, [window.event]);}); } 

并使用这样的

 addEvent(links[i], 'click', [your function here]); 

使用JQuery,以下代码有效:

 function adaptLinks(table, sortableTable) { $('a[href]').click(function (e) { if(!e.isDefaultPrevented()) {  } }); } 

这需要使用额外的库,但避免了addEventListener / attachEvent存在的一些问题(就像后者对此引用的问题)。

只有一个陷阱:如果使用“普通”JavaScript分配原始的onClick处理程序,那么该行

 ... if(!e.isDefaultPrevented()) ... 

将始终解析为true ,即使原始处理程序通过返回false取消了该事件。 要解决这个问题,原始处理程序也必须使用JQuery。

此函数应该可用(事件侦听器方法):

 function addEventListener(element, eventType, eventHandler, useCapture) { if (element.addEventListener) { element.addEventListener(eventType, eventHandler, useCapture); return true; } else if (element.attachEvent) { return element.attachEvent('on' + eventType, eventHandler); } element['on' + eventType] = eventHandler; } 

或者您可以保存更多添加此function的代码(如果您需要将相同的事件侦听器添加到许多元素):

 function addClickListener(element) { addEventListener(element, 'click', clickHandler, false); } 

我以简单的方式遇到重载问题 – 这个页面是一个很好的资源http://www.quirksmode.org/js/events_advanced.html