2012-02-15 5 views
4

Jqueryのバインドは素晴らしいですが、バインディングがどのような順序で行われるかわかりません。私の現在の問題はこうです:同じイベントのイベント発射順序をどのように変更しますか?

$(document.body).delegate('form', methods.checkForm); 
$('form').bind('submit', methods.submitFormIfCheckedFormIsTrue); 

methods.checkForm = function (e) { 
    if (!$(this).isVerified()) { 
     return false; 
    } 
    return true; 
}; 
methods.submitFormIfCheckedFormIsTrue = function (e) { 
    e.preventDefault(); 
    $.ajax("/submitForm", { 
     data:$(this).serialize(), 
     type:"post" 
    }); 
}; 

これは明らかに私が使っている実際のコードではありませんが、かなり近いです。何が起こるかは、submitFormIfCheckedFormIsTrue関数がcheckForm関数の前またはその間に起動するため、チェックがかなり役に立たないということです。私のハックは、フォームに「checked」というクラスを追加し、フォームにそのクラスが他の関数に含まれているかどうかをチェックすることでしたが、submitをクリックしてチェックしてから、もう一度クリックして送信しなければなりませんすべてが正しければ...遅れている。

この問題に関して重要なもう1つのことは、変更できない理由のために、私がアプリケーションの全く異なる部分にあることです。また、それらは非同期にロードされています。

私は、知りたい主なもの...は、順序を変更したり、何らかの形でのイベントの優先順位を設定する方法です...

+0

最初に実行する関数を最初の呼び出しから呼び出しますか? –

+0

なぜajax関数を呼び出して同じ関数内をチェックするだけではないのですか? – loganfsmyth

+0

モジュール化する必要があります。チェック機能はすべてのフォームで一般的ですが、2番目の機能は特定の1つのフォームにのみ固有です。私はちょうど状況につながるものの例としてそのコードを投稿しました... – adiktofsugar

答えて

3

あなたは「デリゲート」あなたはそれで持っている方法を使用している場合あなたの例では、Ajaxの提出は常に最初に実行されるので、あなたの質問への短い答えは「あなたはできません」です。デリゲートは 'body'要素に関連付けられているため、DOMツリーのフォームに近い要素に関連付けられたイベントが最初に起動します。

イベントはフォームから泡立ちますので、そのときは順序はありません。

1つのオプションは、検証トリガーに2番目のイベントを設定することです。

methods.checkForm = function (e) { 
    e.preventDefault() 

    if ($(this).isVerified()) { 
    $(this).trigger('form-verified'); 
    } 
}; 

は、代わりに'submit'に他のハンドラをバインド、あなたは'form-verified'にそれを結合するであろう。

$('form').bind('form-verified', methods.submitFormIfCheckedFormIsTrue); 
これは、デリゲートを使用するのではなく、同じ要素にアタッチされている場合、イベントの順序付けを行う別の方法です。

また、jQuery> = 1.7を使用している場合は、binddelegateの代わりにonを使用する必要があります。 http://api.jquery.com/on/

更新

の両方が同じ要素にバインドされている場合、それらは、それらが要素に接続された順にトリガーされます。 checkFormが他のイベントの前にバインドされていると仮定すると、同じ要素にアタッチされている場合は、return false;は他のイベントの起動を停止しません。そのためにはe.stopImmediatePropagation()も必要です。

methods.checkForm = function (e) { 
    e.preventDefault() 

    if (!$(this).isVerified()) { 
    e.stopImmediatePropagation(); 
    } 
}; 

イベントの順序を調整する必要がある場合は、こちらにも便利な回答があります。 jQuery event handlers always execute in order they were bound - any way around this?

+0

私はそれが好きです。私は本当に私の質問に答えていないにもかかわらず、私はそれを使用している..私はそれがフォームにバインドするようにも変更されました。最初はcheckForm、もう1つはうまくいけば...非同期なので実際にはわかりませんが...それでも同じことをしました。イベントの優先順位を変更する方法はありますか? – adiktofsugar

+0

あなたはそれらを直接フォームに再度添付していますが、依然として間違った順序で実行されていますか?それは意味をなさない。 2番目のものが 'form-verified'にバインドされている場合、最初のものが実行されるまではまったく実行されません。より多くのコードで投稿を更新できますか? – loganfsmyth

+0

いいえ、あなたが与えた答えを使用して、それは動作しますが、私は提出のためのカスタムトリガーを作成する必要はありませんので、私は何をしようとしていた方法を知りたいのですが、依然としてsubmitにバインドしますが、正しい順序で実行します。 – adiktofsugar

0

一般的な意味では、ハンドラはバインドされた順序で呼び出されますが、同じレベルでバインドされている場合にのみ呼び出されます。あなたの場合はフォームに直接バインドする一方、もう1つはdocument.bodyレベルにバインドされた委任ハンドラです。直接バインドされたものが最初に発生し、イベントがバブルアップしてもう一方が処理します。

あなたは.delegate()と同じレベルで、両方のハンドラをバインドする場合、彼らは順番に呼び出されなければなりません。

$(document.body).delegate('form', 'submit', methods.checkForm); 
$(document.body).delegate('form', 'submit', 
            methods.submitFormIfCheckedFormIsTrue); 

そして、最初の(一般的な)ハンドラ内であなたが(と呼ばれている他のハンドラを防ぐためにevent.stopImmediatePropagation() methodを呼び出す必要があります単にfalseを返すこと)デフォルトを防ぎ、さらにバブルアップイベントを停止しますが、それはランニングからそのレベルで他のハンドラを停止しないことに注意:

ところで
methods.checkForm = function (e) { 
    if (!$(this).isVerified()) { 
     e.stopImmediatePropagation(); 
     return false; 
    } 
    return true; 
}; 

(、クエストに示すコード(.delegate()コールからイベント(2番目のパラメータ)を除外しました - 私は自分のコードに入れました)

.delegate()ではなく、両方のハンドラを直接バインドします。 .delegate()を使用している場合、最新バージョンのjQueryを使用している場合は、新しいdo-everythingイベントバインディングメソッド.on()に切り替えることができます。

は間違いなく前に

、いない時に "何が起こるかというとcheckForm機能、submitFormIfCheckedFormIsTrue機能火災の前に、ある、または中"。 (ほぼすべてのブラウザで)JavaScriptは1つのスレッドで実行されるため、同時に2つの関数を実行することはありません。

関連する問題