为了账号安全,请及时绑定邮箱和手机立即绑定

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

/ 猿问

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

慕仙森 2019-09-21 13:50:08

我想举行一个活动,直到我准备解雇它为止


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


   e.preventDefault(); 


   // do lots of stuff


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


}

是否有与上述run()功能等效的功能?


查看完整描述

3 回答

?
拉莫斯之舞

不。一旦事件被取消,便被取消。


不过,您可以稍后使用标志来确定您的自定义代码是否已经运行,从而重新触发该事件-像这样(请忽略公然的名称空间污染):


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!');

    });


查看完整回答
反对 回复 2019-09-21
?
手掌心

接受答案的最新版本。


简要版本:


$('#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();


    }


});


查看完整回答
反对 回复 2019-09-21
?
一只斗牛犬

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

}

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


查看完整回答
反对 回复 2019-09-21

添加回答

回复

举报

0/150
提交
取消
意见反馈 邀请有奖 帮助中心 APP下载
官方微信