発射する準備ができるまでイベントを開催したい
$('.button').live('click', function(e){
e.preventDefault();
// do lots of stuff
e.run() //this proceeds with the normal event
}
run()
上記の機能に相当するものはありますか?
発射する準備ができるまでイベントを開催したい
$('.button').live('click', function(e){
e.preventDefault();
// do lots of stuff
e.run() //this proceeds with the normal event
}
run()
上記の機能に相当するものはありますか?
回答:
いいえ。イベントがキャンセルされると、キャンセルされます。
ただし、フラグを使用してカスタムコードがすでに実行されているかどうかを判断するために、後でこのように(露骨な名前空間汚染を無視してください)、イベントを再起動できます。
var lots_of_stuff_already_done = false;
$('.button').on('click', function(e) {
if (lots_of_stuff_already_done) {
lots_of_stuff_already_done = false; // reset flag
return; // let the event bubble away
}
e.preventDefault();
// do lots of stuff
lots_of_stuff_already_done = true; // set flag
$(this).trigger('click');
});
より一般化されたバリアント(グローバルな名前空間の汚染を回避するという追加の利点がある)は次のとおりです。
function onWithPrecondition(callback) {
var isDone = false;
return function(e) {
if (isDone === true)
{
isDone = false;
return;
}
e.preventDefault();
callback.apply(this, arguments);
isDone = true;
$(this).trigger(e.type);
}
}
使用法:
var someThingsThatNeedToBeDoneFirst = function() { /* ... */ } // do whatever you need
$('.button').on('click', onWithPrecondition(someThingsThatNeedToBeDoneFirst));
ボーナス付きの超ミニマルなjQueryプラグインPromise
:
(function( $ ) {
$.fn.onButFirst = function(eventName, /* the name of the event to bind to, e.g. 'click' */
workToBeDoneFirst, /* callback that must complete before the event is re-fired */
workDoneCallback /* optional callback to execute before the event is left to bubble away */) {
var isDone = false;
this.on(eventName, function(e) {
if (isDone === true) {
isDone = false;
workDoneCallback && workDoneCallback.apply(this, arguments);
return;
}
e.preventDefault();
// capture target to re-fire event at
var $target = $(this);
// set up callback for when workToBeDoneFirst has completed
var successfullyCompleted = function() {
isDone = true;
$target.trigger(e.type);
};
// execute workToBeDoneFirst callback
var workResult = workToBeDoneFirst.apply(this, arguments);
// check if workToBeDoneFirst returned a promise
if (workResult && $.isFunction(workResult.then))
{
workResult.then(successfullyCompleted);
}
else
{
successfullyCompleted();
}
});
return this;
};
}(jQuery));
使用法:
$('.button').onButFirst('click',
function(){
console.log('doing lots of work!');
},
function(){
console.log('done lots of work!');
});
lots_of_stuff_already_done = true;
フラグを設定するのを忘れました-そうでなければ、関数が再帰を続ける方法はありません。
承認された回答の最新バージョン。
簡単なバージョン:
$('#form').on('submit', function(e, options) {
options = options || {};
if ( !options.lots_of_stuff_done ) {
e.preventDefault();
$.ajax({
/* do lots of stuff */
}).then(function() {
// retrigger the submit event with lots_of_stuff_done set to true
$(e.currentTarget).trigger('submit', { 'lots_of_stuff_done': true });
});
} else {
/* allow default behavior to happen */
}
});
このようなものの良い使用例は、機能するレガシーフォームコードがある場合ですが、フォームを送信する前にメールアドレス検証などを追加してフォームを拡張するように求められました。バックエンドフォームのポストコードを掘り下げる代わりに、APIを記述してから、フォームが従来のPOSTを実行する前に、そのAPIを最初にヒットするようにフロントエンドコードを更新できます。
これを行うには、ここで書いたものと同様のコードを実装できます。
$('#signup_form').on('submit', function(e, options) {
options = options || {};
if ( !options.email_check_complete ) {
e.preventDefault(); // Prevent form from submitting.
$.ajax({
url: '/api/check_email'
type: 'get',
contentType: 'application/json',
data: {
'email_address': $('email').val()
}
})
.then(function() {
// e.type === 'submit', if you want this to be more dynamic
$(e.currentTarget).trigger(e.type, { 'email_check_complete': true });
})
.fail(function() {
alert('Email address is not valid. Please fix and try again.');
})
} else {
/**
Do traditional <form> post.
This code will be hit on the second pass through this handler because
the 'email_check_complete' option was passed in with the event.
*/
$('#notifications').html('Saving your personal settings...').fadeIn();
}
});
あなたは次のようなことができます
$(this).unbind('click').click();
次のisDefaultPrevented
ようにプロパティをオーバーライドします。
$('a').click(function(evt){
evt.preventDefault();
// in async handler (ajax/timer) do these actions:
setTimeout(function(){
// override prevented flag to prevent jquery from discarding event
evt.isDefaultPrevented = function(){ return false; }
// retrigger with the exactly same event data
$(this).trigger(evt);
}, 1000);
}
私見、これはまったく同じデータでイベントを再トリガーする最も完全な方法です。
e
未定義です。する必要がありますevt.preventDefault()
。編集を試みましたが、編集は6文字以上である必要があり、2 :(
event.isPropagationStopped = function(){ return false; };
ます。また、イベントにカスタムプロパティを追加して、アクションを妨げるチェックが行われたかどうかをハンドラーで検出できるようにして、再度行われないようにしました。すごい!
使用することが可能であるcurrentTarget
のevent
。例では、フォームの送信を続行する方法を示します。同様に、onclick
属性などから関数を取得できます。
$('form').on('submit', function(event) {
event.preventDefault();
// code
event.currentTarget.submit();
});
submit()
同じ要素を呼び出す場合、「$( 'form')。on( 'submit')コードに戻って何度もやり直すことはありませんか?
実行しないe.preventDefault();
か、条件付きで実行してください。
元のイベントアクションが発生したときに変更することはできません。
しばらくして(たとえば、AJAXリクエストのコールバックで)元のUIイベントを「再作成」する場合は、(vzwickの回答のように)他の方法でそれを偽造する必要があります...そのようなアプローチの有用性に疑問を投げかける。
より最近の回答が巧みに使用されています jQuery.one()
$('form').one('submit', function(e) {
e.preventDefault();
// do your things ...
// and when you done:
$(this).submit();
});
「たくさんのもの」が非同期で何かを実行していない限り、これは絶対に不要です。イベントは順番にすべてのハンドラーを順番に呼び出します。そのため、親要素にonklick-eventがある場合、onclik-の後に起動します子供のイベントは完全に処理されました。JavaScriptは、イベント処理の「停止」を必要とする、ある種の「マルチスレッド化」をここでは行いません。結論:同じハンドラーで再開するためだけにイベントを「一時停止」しても、意味がありません。
「ものの多く」が非同期のものである場合、それはまた、彼らがやるべきことを非同期的に行うのを防ぎ(非同期のもの)、すべてが順番に並んでいるように振る舞うようにするので意味がありません(最初の段落に戻ります) )
async
-fag:api.jquery.com/jQuery.ajax)...しかし、同期ajaxリクエストを作成することは、ほとんどすべての場合に悪い考えです。したがって、別の解決策を見つける方が良いでしょう。
私が使用するアプローチはこれです:
$('a').on('click', function(event){
if (yourCondition === true) { //Put here the condition you want
event.preventDefault(); // Here triggering stops
// Here you can put code relevant when event stops;
return;
}
// Here your event works as expected and continue triggering
// Here you can put code you want before triggering
});
アンカータグを使用している場合、承認されたソリューションは機能しません。この場合、を呼び出した後、リンクを再度クリックすることはできませんe.preventDefault()
。これは、jQueryによって生成されたクリックイベントが、ネイティブブラウザーイベントの上にあるためです。したがって、アンカータグで「クリック」イベントをトリガーしても、リンクはたどられません。代わりに、ネイティブブラウザーイベントを起動できるjquery-simulateなどのライブラリを使用できます。
これに関する詳細はこのリンクで見つけることができます
この例が役立つ場合は、いくつかのリンクに「カスタム確認ポップイン」を追加します(「$ .ui.Modal.confirm」のコードを保持します。これは、元のアクションを実行するコールバックの単なる例です)。
//Register "custom confirm popin" on click on specific links
$(document).on(
"click",
"A.confirm",
function(event){
//prevent default click action
event.preventDefault();
//show "custom confirm popin"
$.ui.Modal.confirm(
//popin text
"Do you confirm ?",
//action on click 'ok'
function() {
//Unregister handler (prevent loop)
$(document).off("click", "A.confirm");
//Do default click action
$(event.target)[0].click();
}
);
}
);