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

rlu*_*uba 17 javascript jquery onclick

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

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

function adaptLinks()
{
    var links = document.getElementsByTagName('a');
    for(i = 0; i != links.length; i++)
    {
        links[i].onclick = function (e)
        {
            <do some work>
            return true;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但是一些链接已经有一个应该保留的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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

ann*_*ata 20

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

这里介绍好.


Gra*_*ner 17

您需要创建一个闭包来保留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>
Run Code Online (Sandbox Code Playgroud)

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

更多关于comp.lang.javascript FAQDouglas Crockford的闭包.