我想举行一个活动,直到我准备解雇它为止
$('.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()
功能等效的功能?
Answers:
不。一旦事件被取消,便被取消。
不过,您可以稍后使用标志确定您的自定义代码是否已经运行,从而重新触发该事件-诸如此类(请忽略公然的名称空间污染):
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,然后更新您的前端代码以首先命中该API,然后再允许表单执行传统的POST。
为此,您可以实现类似于我在此处编写的代码:
$('#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; };
。我还向事件添加了一个自定义属性,以便可以在处理程序中检测是否阻止了该操作的检查已完成,因此不再进行检查。大!
最近的答案巧妙地使用了 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生成的click事件只是本机浏览器事件之上的一层。因此,在锚标记上触发“点击”事件将不会跟随该链接。相反,您可以使用类似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();
}
);
}
);