2

在 jQuery 中,我试图向已经有一个“提交”绑定的表单添加一个“提交”绑定,但我需要在预先存在的绑定之前触发新的(第二个)绑定(回调)。

有没有办法让我插入一个绑定,以便它在已经附加的绑定之前触发?

4

4 回答 4

2

你可以使用$._data( $("#myform")[0], "events" ).submit

查看单击事件的示例 jsfiddle:

http://jsfiddle.net/X9hat/

于 2013-04-15T14:45:04.643 回答
2

使用未记录的对绑定函数的访问,假设您的表单具有 id a,您可以像这样颠倒处理程序调用的顺序:

[].reverse.call($._data($('#a').get(0)).events.submit);

演示(点击“用JS运行”,打开控制台,然后点击“点击”按钮)

请注意,此结构未记录且不保证

请注意,这不是受支持的公共接口;实际数据结构可能因版本而异。

所以真正的解决方案是更改第一个绑定代码。

于 2013-04-15T14:48:47.313 回答
1

在回调中触发第一个绑定到新的(第二个)绑定:How to order events bound with jQuery

于 2013-04-15T14:43:23.287 回答
0

我知道这有点晚了,但是jQuery 在 v1.7 及更高版本中公开了这一点。我有一个会议,当我回来时会把它变成一个工作示例......如果我回来......祝我好运。

#fiddle 这会关闭点击事件,但您可以将其切换为通过思考提交

html

从 jsfiddle 重新发布 html

<form>
    <p>before click</p>
    <button type="button">start</button>
</form>

javascript

从 jsfiddle 重新发布 javascript

var $elem = $("button"), //jqElementObject
    elem=$elem[0], //html element object
    eventNameKey="click", //name of the event we want to alter
    eventHandlerKey="handler"; //jQuery private object reference to get the actual function ref

 $elem.click(function(ev){
     //this happens somewhere else, pretend we can't control it per your comments
    console.log("1");
    ev.preventDefault();
  $("p").text($("p").text()+"<div>first binding</div>");
});
//this is ours, we can control this
function submitControler(ev){
        console.log("2");
  ev.preventDefault();
  $("p").text($("p").text()+"<div>second binding</div>");
    //uncomment below to stop propogation
    //return false;
}
$elem.click(submitControler); //actually register our event
$elem.click(function(ev){ //third event for some fun
ev.preventDefault();
  $("p").text($("p").text()+"<div>third binding</div>");
});

 var officialEvents = $._data(elem,"events"), //jQuery official Private events
    ourSubmitEvents = $.Callbacks("unique stopOnFalse"); //default Callbacks values promises to behave like a standard events list, however, you want your event to fire first, then others to proceed if it returns true.  also, no duplicates just because.

//I'm running out of time, so i went with a for loop. I wanted a way to find our event where the registration order was not guaranteed, feel free to go for something better
for(var event = officialEvents[eventNameKey].length-1; event >-1; event--){
    if(officialEvents[eventNameKey][event][eventHandlerKey] ===submitControler){
      ourSubmitEvents.add(officialEvents[eventNameKey][event][eventHandlerKey]);
      console.log("added primary controler");
      break;
    }
}
//add in everyone else to our list, again, i'm out of time and a for loop was the first thought i had.  feel free to improve
for(var event = 0; event < officialEvents[eventNameKey].length; event++){
    if(officialEvents[eventNameKey][event][eventHandlerKey] !==submitControler){
      ourSubmitEvents.add(officialEvents[eventNameKey][event][eventHandlerKey]);
        console.log("added secondary controler");
    }
}
//this is our event scheduler, it will be first to execute, and calls our manually re-ordered 'ourSubmitEvents' object. ('ourSubmitEvents' becomes 'ev.data')
$elem.on({"click":function(ev){
    ev.preventDefault();
  ev.data.fire(ev);
}},null,ourSubmitEvents);
//remove the other events, except the one we just registered.
$._data(elem,"events")[eventNameKey].splice(0,officialEvents[eventNameKey].length-1);
于 2013-04-15T15:01:10.773 回答