我正在尝试修改网页上的所有链接,以便他们在点击时执行一些额外的工作。
一个简单的方法可能是这样的:
function adaptLinks()
{
var links = document.getElementsByTagName('a');
for(i = 0; i != links.length; i++)
{
links[i].onclick = function (e)
{
<do some work>
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;
}
<do some work>
return true;
}
}
}
但这不起作用,因为 oldOnClick 仅在调用处理程序时进行评估(它包含 last 链接的值作为此点)。
答案 0 :(得分:19)
不要直接分配给事件处理程序:使用订阅模型 addEventListener / attachEvent (它也有删除对!)。
好的介绍here。
答案 1 :(得分:16)
您需要创建一个闭包以保留每个链接的原始onclick
值:
<a href="#" onclick="alert('hi');return false;">Hi</a>
<a href="#" onclick="alert('there');return true;">There</a>
<script type="text/javascript">
function adaptLinks() {
var links = document.getElementsByTagName('a');
for (i = 0; i != links.length; i++) {
links[i].onclick = (function () {
var origOnClick = links[i].onclick;
return function (e) {
if (origOnClick != null && !origOnClick()) {
return false;
}
// do new onclick handling only if
// original onclick returns true
alert('some work');
return true;
}
})();
}
}
adaptLinks();
</script>
请注意,如果原始onclick处理程序返回true,则此实现仅执行新的onclick处理。如果这是你想要的,那就没关系了,但请记住,如果你想要执行新的onclick处理,即使原始处理程序返回false,你也必须稍微修改一下代码。
答案 2 :(得分:4)
在addEventListener(支持DOM的浏览器)或attachEvent(IE)周围使用包装。
请注意,如果您希望在不覆盖旧值的情况下将值存储在变量中,则可以使用closures。
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);
在Aspect Oriented Programming中,这被称为“advice”。
答案 3 :(得分:0)
如何设置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;
//<do some work>
return true;
}
或者您可以像其他人推荐的那样使用attachEvent
和addEventListener
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]);
答案 4 :(得分:0)
使用JQuery,以下代码可以工作:
function adaptLinks(table, sortableTable)
{
$('a[href]').click(function (e)
{
if(!e.isDefaultPrevented())
{
<do some work>
}
});
}
这需要使用额外的库,但避免了addEventListener / attachEvent存在的一些问题(就像后者对this references的问题)。
只有一个陷阱:如果使用“普通”JavaScript分配原始 onClick 处理程序,那么该行
...
if(!e.isDefaultPrevented())
...
将始终解析为<strong> true ,即使原始处理程序通过返回false取消了该事件。要解决这个问题,原始处理程序也必须使用JQuery。
答案 5 :(得分:0)
此函数应该可用(事件侦听器方法):
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 addClickListener(element) {
addEventListener(element, 'click', clickHandler, false);
}
答案 6 :(得分:0)
我以简单的方式遇到重载问题 - 这个页面是一个很好的资源 http://www.quirksmode.org/js/events_advanced.html