javascript - 在 javascript 中,如何包装 onclick 回调?

标签 javascript

我想装饰或包装特定的 onclick 回调,以便在调用原始安装的回调后执行我的代码。

我开始这样做是为了使用带有闭包的函数生成器以半Python的方式来完成它:

var original_onclick = node.onclick;
function wrapper_onclick() {
    original_onclick.apply(this,arguments);
    my_code();
}
node.onclick = wrapper_onclick;

但是,当我使用上面的代码时,原来的回调无法正常工作。我是否传入了错误的第一个参数(上下文参数?)this。我需要调整参数吗? this 是否已在列表 arguments 中?

最佳答案

这正是许多人努力寻找跨浏览器事件监听的正确解决方案的原因。有些浏览器不会在正确的上下文中触发该函数,有些浏览器不会传递事件参数等等。使用框架要容易得多,但如果你坚持不使用框架......

首先,如果你有非常糟糕的代码,例如:

<a href="javascript:someFunction( this , evaledVariable );otherFn( ohDearVariable )">

那么抱歉,没有人可以帮助您。

否则...

无论如何,您都不能通过简单地设置 .onclick 属性来将事件直接附加到节点,并期望它在跨浏览器上表现相同,甚至在您正在开发的浏览器中正常工作和。您必须同时使用 addEventListenerattachEvent 方法。

跨浏览器事件最简单的 fork 方法是:

var addListener = function( node , event , listener ) {

    if ( node.addEventListener ) {

        node.addEventListener( event , listener , false );

    } else if (node.attachEvent ) {

        node.attachEvent( "on" + event , listener );

    }

}

与删除监听器相同:

var removeListener = function( node , event , listener ) {

    if ( node.addEventListener ) {

        node.removeEventListener( event , listener , false );

    } else if (node.attachEvent ) {

        node.detachEvent( "on" + event , listener );

    }

}

并这样使用它:

var nodeListener = function( e ) {
    alert(e.target);
    // run once for demo
    removeListener( node , "click" , nodeListener );
}
// notice we omit the "on" part.
addListener( node , "click" , nodeListener );

因此,如果您想以错误的 onclick 方式包装附加到节点的监听器:

var wrongOnClick = node.onclick;

var listener = function( e ) {
    before();
    wrongOnClick.call( this , e );
    after();
};

addListener( node , "click" , listener );

这将为包括 IE 在内的大多数现代浏览器提供服务,尽管实际上需要更多的优化和内存泄漏预防代码才能实现良好的实现,但不要自己编写此代码或让其他人为您编写此代码,而是使用框架/tookit !因为当您有一个可以跨浏览器运行的良好实现时,您将比实际使用框架时有更多的代码膨胀......

** 附录 **

作为一种技巧,我仍然建议使用 addEventListener 方法并保留对监听器的引用。

var aListener = function( e ) { }
node.addEventListener( "click" , aListener , false );

var wrappedListener = function ( e ) {
   before( e );
   aListener( e );
   after( e );
}
node.removeEventListener( "click" , aListener , false );
node.addEventListener( "click" , wrappedListener , false );

这显然只适用于您的监听器,如果您希望它将现有监听器包装在页面中(来自其他人的监听器),那么根本无法知道人们如何将监听器附加到节点。如果他们使用了 addEventListener/attachEvent 库或本文开头的肮脏示例,那么如果不手动编码、查找引用或手动公开它们,您根本无法可靠地包装它们。

关于javascript - 在 javascript 中,如何包装 onclick 回调?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4089458/

相关文章:

javascript - 如何显示js警报弹出框,其中特定单词作为点击链接?

javascript - 如何从 async/await 函数正确返回结果?

php - jQuery 根据字符数更改 CSS 中的行高

javascript - JQuery Datepicker - 将选定的日期发送到新页面,将其用作 php 变量

javascript - 由于 php 结果更改 html 中的类和文本

javascript - jQuery AJAX 发布;不发帖

javascript - 选择表单的值 - JavaScript

javascript - 访问 <div> 中的 <span> 文本

javascript - 使用 url 标签滚动到特定 div

javascript - 动态图像 slider 到 asp.net mvc c# 中的动态卡片