2013-04-15 3 views
2

В jQuery я пытаюсь добавить привязку «отправить» к форме, которая уже имеет одно обязательство «отправить», но мне нужно новое (второе) связывание (обратный вызов) до уже существующего.вставка jQuery привязки перед другим связыванием

Есть ли способ установить привязку, чтобы она срабатывала перед привязкой, которая уже была прикреплена?

ответ

2

Вы можете использовать $._data($("#myform")[0], "events").submit

Смотрите пример jsfiddle для события Click:

http://jsfiddle.net/X9hat/

+0

+1. Отличная скрипка и отличный ответ. Мое намерение состоит в том, чтобы запретить другие привязки, но когда я верну ложь из недавно вставленного связывания, я считаю, что это не мешает другим действиям. (http://jsfiddle.net/X9hat/1/) Можете ли вы сказать мне, что мне нужно сделать, чтобы предотвратить другие привязки? (Я не хочу полностью их потерять.Новое первое связывание должно выполнить проверку валидации, а затем определить, должны ли другие стрелять.) – JellicleCat

+0

Я посмотрю, скоро ли я найду решение. –

+0

Найденный. Благодарю. Я получаю обратный вызов и отвязываю оригинальную привязку с: '$ ._ data ($ (" # pq-new-quoter ") [0]," events ") .submit.pop(). Handler;' – JellicleCat

1

Активизируйте первое связывание в обратном вызове на новый (второй) связывание: How to order events bound with jQuery

+0

Итак, можно ли отменить первый обратный вызов и по-прежнему иметь ссылку на эту функцию, чтобы я мог привязать его к новой функции обратного вызова? (Исходная функция обратного вызова инкапсулирована, поэтому я не могу назвать ее по имени.) – JellicleCat

+0

@JellicleCat, почему отвязать? Просто не связывайте первый обратный вызов, пока вы не привяжете его в обратном вызове ко второй привязке. –

+0

Я использую сторонний скрипт из CDN, поэтому я не могу изменить оригинальную привязку. – JellicleCat

2

Использования недокументированный доступ к связанным функциям, если ваша форма имеет идентификатор a, вы можете изменить порядок вызовов обработчика следующим образом:

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

Demonstration (Нажмите кнопку "Запуск с JS", откройте консоль, а затем нажмите кнопку "мыши")

Обратите внимание, что эта структура undocumented and without guarantee:

Обратите внимание, что это не поддерживаемый публичный интерфейс; фактические данные структуры могут изменяться несовместимо с версии на версию.

Таким образом, реальным решением было бы изменить первый код привязки.

+0

Thx для обеспечения полезного информация о! –

+0

+1 для напоминания всем, что вызовы $ ._ data() не гарантированы – DefyGravity

0

Я знаю, что это немного поздно, но jQuery exposed this in v1.7 and higher. У меня встреча и превращу это в рабочий пример, когда я вернусь ... если я вернусь ... желаю мне удачи.

#fiddle это сбегает событие щелчка, но вы можете переключить его представить с мыслью

HTML

перепроведением HTML, из jsfiddle

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

яваскрипт

перепроведения javascript от jsfiddle

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); 
+0

Очень круто. Пожалуйста, предоставьте рабочий пример. – JellicleCat

+0

также, не стесняйтесь использовать более короткий ответ @dystroy ниже. все, что попадает в $ ._ data(), является единственным способом, я использовал $ .CallBacks() для организации манипуляций с событиями и для более тонкого управления зерном – DefyGravity

Смежные вопросы