0

I have to call another function before the original onclick event fires, I've tried a lot of different paths before I've come to following solution:

function bindEnableFieldToAllLinks() {
    var links = document.getElementsByTagName('a');
    for (var i = 0; i < links.length; i++) {
        var link = links[i];
        var onclick = link.getAttribute('onclick');
        link.onclick = new Function("if(linkClickHandler()){"+onclick+"}");
        console.log(link.getAttribute('onclick'));
    }
}

This does the trick in firefox and chrome but IE8 is acting strange, it seems that the function that's in the onclick variable isn't executed,
I've allready added console.log messages that get fired after the if statement is true and if I print out the onclick attribute I get following:

LOG: function anonymous() {
if(linkClickHandler()){function onclick()
{
if(typeof jsfcljs == 'function'){jsfcljs(document.getElementById('hoedanigheidForm'),      {'hoedanigheidForm:j_id_jsp_443872799_27':'hoedanigheidForm:j_id_jsp_443872799_27'},'');}return false
}}
}

So it seems that the function is on the onclick of the link and the old onclick function is on it asswell.
Can anyone help me out with this please?

Thanks

4

2 回答 2

1

假设您在HTMLElement上有一个onclick属性..

<span id="foo" onclick="bar"></span>

现在,

var node = document.getElementById('foo');
node.getAttribute('onclick'); // String "bar"
node.onclick; // function onclick(event) {bar}

后者看起来对你想要达到的目标更有用,因为使用它仍然有它原来的范围,你不必evalFunction.

function bindEnableFieldToAllLinks() {
    var links = document.getElementsByTagName('a'),
        i;
    for (i = 0; i < links.length; i++) function (link, click) { // scope these
        link.onclick = function () { // this function literal has access to
            if (linkClickHandler())  // variables in scope so you can re-
                return click.apply(this, arguments); // invoke in context
        };
    }(links[i], links[i].onclick); // pass link and function to scope
}

此外,在onclick属性中设置命名函数(即作为String)并不能实现任何效果。该函数不会调用,甚至不会进入全局命名空间,因为它被包装了。 设置一个匿名的会更糟糕,并且会在onclick尝试执行时抛出一个SyntaxError 。

于 2013-07-09T13:19:44.613 回答
1

这将做你想做的事,首先执行里面的内容linkClickHandler,然后执行onclick事件。我添加了一个基本的跨浏览器事件订阅功能供您重用。

bindEnableFieldToAllLinks();    

function bindEnableFieldToAllLinks() {
    var links = document.getElementsByTagName('a');
    for (var i = 0; i < links.length; i++) {
        var link = links[i];
        var onclick = link.getAttribute('onclick');
        onEvent(link, 'click', function() { 
            linkClickHandler(onclick);
        });
        link.onclick = undefined;
    }
}

function onEvent(obj, name, func) {
    if (obj.attachEvent) obj.attachEvent('on' + name, func);
    else if (obj.addEventListener) obj.addEventListener(name, func);    
}
function linkClickHandler(funcText) {
    alert('before');
    var f = Function(funcText);

    f();
    return true;
}

jsFiddle

于 2013-07-09T13:22:28.780 回答