【问题标题】:Wrap jquery event handler around hardcoded handler围绕硬编码处理程序包装 jquery 事件处理程序
【发布时间】:2012-12-20 06:38:34
【问题描述】:

我有几个类似这样的表格:

<form id=myForm onsubmit="saveFormData(this);return false">
....
</form>

提交后,执行自定义函数,并取消默认操作(通过http发送数据)。

但现在我需要验证表单,如果验证正常,则触发自定义函数(在这种情况下为saveFormData,但其他表单可能不同),否则什么也不做。

所以最终的事件处理程序应该像这样工作:

$('#myForm').submit(function(){
    if(formValidatesOk(this))
        saveFormData() ;
    return false ;
}

但是,我无法更改 HTML 代码,因此我需要一种通用的方法来重新定义 onsubmit 事件,方法是使用 jquery 事件处理程序包装硬编码的处理程序。

我首先想到的是(未经测试):

var hardcodedHandler = $('#myForm').prop('onsubmit') ; // save the current handler
$('#myForm').prop('onsubmit',null) ; // remove the current handler
$('#myForm').submit(function(){
    if(formValidatesOk(this)) // if the form is valid then...
        Function(hardcodedHandler).call(this) ; // trigger the original handler
    return false ;
}) ;

但这不是很优雅(至少可以这么说)。

你知道更好的方法吗?

【问题讨论】:

  • formValidatesOk 有什么异步的吗?如果不是,当formValidatesOk 的结果是false 时,你为什么不only return false;?因此逻辑将是“如果 formValidatesOk 返回 true,则还执行原始 onsubmit...否则,停止默认行为(返回 false)”。这将是if (!formValidatesOk(this)) return false;,就是这样。或者您是说您不希望默认行为发生?
  • 我不想通过 http 提交表单。但我确实希望在表单验证正常时触发硬编码处理程序(示例中为saveFormData)。
  • @Ian,我如何确定 jquery 处理程序会在硬编码处理程序之前触发?
  • 啊,我明白了,我没有想到这一点。这就是为什么我想把它说出来:) 我会看看 Bergi 的回答......没想到 prop 会不同于 attr 并得到你真正想要的

标签: javascript jquery html forms validation


【解决方案1】:

你可以从元素的onsubmit属性中获取旧函数,你不需要eval它:

var form = $('#myForm');
var oldHandler = form.prop("onsubmit");
form.removeProp("onsubmit").submit(function(e){
    e.preventDefault();
    if(formValidatesOk(this))
        oldHandler.call(this, e);
});

Demo at jsfiddle.net

【讨论】:

    【解决方案2】:

    事件是不可预测的(以它们被触发的方式)。我认为受制于他们的搬运工也不能依赖秩序。因此,将处理程序绑定到更改先前添加的处理程序的事件肯定是(非常)不好的做法。实际上,正如您所建议的,您永远无法确定首先触发哪个处理程序。毕竟,事件不应该相互通知。应该使用事件和处理程序来避免代码的高度耦合。

    解决这个问题的最好方法(考虑到你的限制)是用新的行为来装饰你的“旧”处理程序。 Bergi 发布了一个很好的例子。

    【讨论】:

    • 我很确定事件总是按照它们被绑定的顺序执行。当然,OP 是另一种情况,因为有些是与 jQuery 绑定的,有些是内联的。但在这种情况下,内联的应该首先执行,因为它们首先被绑定(一旦元素被解析/渲染)
    • 伊恩,感谢您的评论!它应该是处理程序而不是事件,我会更新我的答案。事件是不可预测的事件,处理程序是向它们注册的函数。尽管如此,我认为不应该依赖它们的顺序,事件和处理程序的添加方式。此外,处理程序不应相互通知。如果是这样,请将它们包装在一个处理程序中以确保正确的顺序和正确的执行(检查依赖的函数是否正确执行)。当然,jQuery 实现会按照它们添加的顺序执行它们,但这是“只是”实现。
    猜你喜欢
    • 2019-11-18
    • 2011-09-13
    • 1970-01-01
    • 2014-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-10
    相关资源
    最近更新 更多