如何在使用event.preventDefault()后触发事件

Ash*_*Ash 138 jquery jquery-events

我想举办一个活动,直到我准备开火,例如

$('.button').live('click', function(e){

   e.preventDefault(); 

   // do lots of stuff

   e.run() //this proceeds with the normal event    

}
Run Code Online (Sandbox Code Playgroud)

是否有与上述run()功能相同的功能?

vzw*_*ick 146

不.事件取消后,将被取消.

您可以稍后重新启动该事件,使用标志来确定您的自定义代码是否已经运行 - 例如这样(请忽略明显的命名空间污染):

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');
});
Run Code Online (Sandbox Code Playgroud)

一个更通用的变体(具有避免全局命名空间污染的额外好处)可以是:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

var someThingsThatNeedToBeDoneFirst = function() { /* ... */ } // do whatever you need
$('.button').on('click', onWithPrecondition(someThingsThatNeedToBeDoneFirst));
Run Code Online (Sandbox Code Playgroud)

Bonus超简约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));
Run Code Online (Sandbox Code Playgroud)

用法:

$('.button').onButFirst('click',
    function(){
        console.log('doing lots of work!');
    },
    function(){
        console.log('done lots of work!');
    });
Run Code Online (Sandbox Code Playgroud)

  • .live被贬低了.使用.on用于下面的@Cory Danielson示例. (4认同)
  • @HimanshuPathak - 你可能忘了设置`lots_of_stuff_already_done = true;`标志 - 否则该函数无法继续递归. (4认同)

Cor*_*son 69

接受答案的最新版本.

简要版本:

$('#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 */
    }

});
Run Code Online (Sandbox Code Playgroud)



对于这样的事情,一个很好的用例是你可能有一些有效的遗留表单代码,但是在提交表单之前,你已经被要求通过添加诸如电子邮件地址验证之类的内容来增强表单.您可以编写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();

    }

});
Run Code Online (Sandbox Code Playgroud)

  • “而不是挖掘后端表单邮政代码”......事实上你无论如何都必须这样做,你不能仅仅依赖客户端验证。 (2认同)

Raf*_*ira 18

你可以做点什么

$(this).unbind('click').click();
Run Code Online (Sandbox Code Playgroud)

  • 你为什么要审查"痛苦"这个词? (47认同)
  • @SeanKendle好问题...现在不要为什么,哈哈. (6认同)
  • $(本).unbind( '点击')的触发器( '点击').应该在IE上工作 (4认同)

小智 12

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);
}
Run Code Online (Sandbox Code Playgroud)

恕我直言,这是用完全相同的数据重新触发事件的最完整方式.

  • @kevnk,我通常以行注释的形式包含编辑的简短描述.这应该会增加提交的字符数. (2认同)

小智 8

它是可以使用currentTargetevent.示例显示了如何继续表单提交.同样,您可以从onclick属性等获取功能.

$('form').on('submit', function(event) {
  event.preventDefault();

  // code

  event.currentTarget.submit();
});
Run Code Online (Sandbox Code Playgroud)


Lig*_*ica 7

只是不要执行e.preventDefault();,或有条件地执行它.

原始事件动作发生,您当然无法改变.

如果你想在一段时间之后"重新创建"原始的UI事件(例如,在AJAX请求的回调中),那么你只需要以其他方式伪造它(比如在vzwick的答案中)......虽然我是质疑这种方法的可用性.


Ora*_*s13 5

最近的答案巧妙地使用了 jQuery.one()

$('form').one('submit', function(e) {
    e.preventDefault();
    // do your things ...

    // and when you done:
    $(this).submit();
});
Run Code Online (Sandbox Code Playgroud)

/sf/answers/2900863171/