Event.preventDefault () का उपयोग करने के बाद किसी घटना को कैसे ट्रिगर करें


155

मैं एक ईवेंट आयोजित करना चाहता हूं जब तक कि मैं इसे आग लगाने के लिए तैयार न हो जाऊं

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

   e.preventDefault(); 

   // do lots of stuff

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

}

क्या run()ऊपर वर्णित फ़ंक्शन के बराबर है ?


डिफ़ॉल्ट व्यवहार केवल आपके हैंडलर के वापस आने के बाद होता है। यह केवल अपने हैंडलर में बाद में अनुमति देने के लिए उस व्यवहार को रोकने के लिए बहुत कम समझ में आता है।
Frédéric Hamidi

7
@ Frédéric Hamidi दुर्भाग्य से, async सामान ($ .ajax, कॉलबैक, आदि) डिफ़ॉल्ट व्यवहार होने की अनुमति देगा।
vzwick

जवाबों:


164

नहीं। एक बार घटना रद्द होने के बाद, इसे रद्द कर दिया गया है।

आप इस घटना को बाद में फिर से आग लगा सकते हैं, एक झंडे का उपयोग करके यह निर्धारित करने के लिए कि आपका कस्टम कोड पहले से ही चला है या नहीं - जैसे कि (कृपया नाममात्र के प्रदूषण की अनदेखी करें):

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

Promiseसमर्थन के साथ बोनस सुपर-न्यूनतर jQuery प्लगइन :

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

4
.live वंचित है। नीचे दिए गए @Cory Danielson उदाहरण में उपयोग किए गए .on का उपयोग करें।
nwolybug

यह फिर से मिल रहा है। क्लिक करें और अंत में मैं "बहुत अधिक पुनरावृत्ति" देखता हूं
हिमांशु पाठक

5
@ हिमांशुपाठक - आप शायद lots_of_stuff_already_done = true;झंडा लगाना भूल गए - अन्यथा समारोह को रोकने का कोई तरीका नहीं है।
vzwick

73

स्वीकृत उत्तर का एक और हालिया संस्करण।

संक्षिप्त संस्करण:

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

});



इस तरह से कुछ के लिए एक अच्छा उपयोग मामला है जहाँ आप कुछ विरासत प्रपत्र कोड हो सकता है कि काम करता है, लेकिन आप फार्म जमा करने से पहले ईमेल पते सत्यापन जैसे कुछ जोड़कर प्रपत्र को बढ़ाने के लिए कहा गया है। बैक-एंड फॉर्म पोस्ट कोड के माध्यम से खुदाई करने के बजाय, आप एक एपीआई लिख सकते हैं और फिर अपने एपीआई को पारंपरिक 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();

    }

});

1
"बैक-एंड फॉर्म पोस्ट कोड के माध्यम से खुदाई करने के बजाय" ... वास्तव में आपको इसे वैसे भी करना होगा, आप अकेले क्लाइंट-साइड सत्यापन पर भरोसा नहीं कर सकते।
डिएगो वी।

18

आप कुछ ऐसा कर सकते हैं

$(this).unbind('click').click();

यह एक बहुत अच्छा समाधान है - लेकिन IE10 / 11 पर काम नहीं करता है, (
16

47
आपने "दर्द" शब्द को सेंसर क्यों किया?
सीन केंडल

आपने क्लिक को ट्रिगर किया लेकिन क्या आप फिर से क्लिक कर सकते हैं?
टॉम एंडरसन

16

संपत्ति 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);
}

IMHO, यह बिल्कुल उसी डेटा के साथ ईवेंट को पुन: व्यवस्थित करने का सबसे पूर्ण तरीका है।


eअपरिभाषित है। होना चाहिए evt.preventDefault()। मैंने संपादित करने का प्रयास किया, लेकिन मेरे संपादन में> 6 वर्ण होने चाहिए और मैंने सिर्फ 2 :(
kevnk

3
@kevnk, मैं आमतौर पर एक पंक्ति टिप्पणी के रूप में संपादन का एक संक्षिप्त विवरण शामिल करता हूं। यह प्रस्तुत वर्ण गणना में वृद्धि करनी चाहिए।
recurse

पता नहीं क्यों इस जवाब को अधिक नहीं बताया गया था, यह वास्तव में उपयोगी है। प्रचार के साथ काम करना भी बंद हो जाता है event.isPropagationStopped = function(){ return false; };। मैंने इवेंट में एक कस्टम प्रॉपर्टी भी जोड़ी ताकि मैं हैंडलर में पता लगा सकूं कि अगर चेक रोका गया तो कार्रवाई फिर से हो गई। महान!
काददथ

मैं बूटस्ट्रैप 4 टैब्स के लिए इस्तेमाल किया, यह पूरी तरह से ठीक काम किया। बहुत धन्यवाद। $ ('# v-tablets-tab a')। ('क्लिक', फंक्शन (e) {e.preventDefault (), setTimeout (फंक्शन () {e.isDefaultPrevented = function ()) पर लौटें;} $ () '# वी-पिल्स-होम-टैब')। ('दिखाया.बीएस.टैब', फंक्शन () {$ ('। मेन डैशबोर्ड')। शो (); $ ('# चेंजप्लांस')। Hide (); });}; 1000); $ (यह) .tab ('शो');});
सूर्य आर प्रवीण

8

यह उपयोग करना संभव है currentTargetकी event। उदाहरण दिखाता है कि फॉर्म सबमिट के साथ कैसे आगे बढ़ना है। इसी तरह आप onclickविशेषता आदि से कार्य प्राप्त कर सकते हैं ।

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

  // code

  event.currentTarget.submit();
});

सबमिट एक मान्य फ़ंक्शन नहीं है
डेवफ़ेयर

यदि आप submit()एक ही तत्व पर कॉल करते हैं, तो क्या आप अपने `` $ ('फॉर्म') पर वापस नहीं आएंगे। ('सबमिट') कोड और इसे बार-बार रीडू करें?
फैनी वेद

7

बस प्रदर्शन नहीं करते हैं e.preventDefault();, या सशर्त प्रदर्शन नहीं करते हैं।

आप निश्चित रूप से नहीं बदल सकते हैं जब मूल घटना कार्रवाई होती है।

यदि आप कुछ समय बाद मूल UI घटना को फिर से बनाना चाहते हैं (कहते हैं, एक AJAX अनुरोध के लिए कॉलबैक में) तो आपको बस इसे कुछ अन्य तरीके से (जैसे vzwick के उत्तर में) नकली करना होगा ... हालांकि मैं इस तरह के दृष्टिकोण की प्रयोज्यता पर सवाल उठाएं।



3

जब तक "बहुत सारा सामान" कुछ अतुल्यकालिक नहीं कर रहा है यह बिल्कुल अस्वाभाविक है - घटना क्रम में प्रत्येक हैंडलर को अपने रास्ते पर बुलाएगी, इसलिए यदि माता-पिता के तत्व पर एक onclick- घटना होती है तो यह ऑनक्लिक के बाद आग लग जाएगी बच्चे की घटना पूरी तरह से संसाधित हो गई है। जावास्क्रिप्ट यहाँ "मल्टीथ्रेडिंग" के कुछ प्रकार नहीं करता है जो इवेंट प्रोसेसिंग नेक्सेसरी को "रोकना" बनाता है। निष्कर्ष: एक घटना को केवल उसी हैंडलर में फिर से शुरू करने के लिए "रुकने" का कोई मतलब नहीं है।

यदि "सामान के बहुत सारे" है इस अतुल्यकालिक कुछ भी मतलब नहीं है के रूप में यह एसिंक्रोनस चीजों से बचाता है उन्हें क्या करना चाहिए (एसिंक्रोनस सामान) और उन्हें बाहवे बनाने की तरह सब कुछ क्रम में है (जहां हम अपने पहले पैराग्राफ के लिए वापस आने के लिए क्या करने के लिए )


बीच में प्रक्रिया अतुल्यकालिक है, मैं अजाक्स कॉलबैक में परिणाम आग करना चाहता हूँ ...
Mazatec

1
अगर आपको एक अजाक्स-अनुरोध के लिए इंतजार करना पड़ता है, तो इसे सिंक्रोनस बनाएं (jquery के लिए, async-fag: api.jquery.com/jQuery.ajax ) ... लेकिन synchonous ajax-request करना लगभग हर मामले में एक बुरा विचार है, इसलिए बेहतर होगा कि इसका कोई अलग हल निकालें।
oezi

3

मेरे द्वारा उपयोग किया जाने वाला तरीका यह है:

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

2

यदि आप एक एंकर टैग के साथ काम कर रहे हैं तो स्वीकृत समाधान नहीं होगा। इस स्थिति में आप कॉल करने के बाद फिर से लिंक पर क्लिक नहीं कर पाएंगे e.preventDefault()। क्योंकि jQuery द्वारा उत्पन्न क्लिक इवेंट देशी ब्राउज़र घटनाओं के शीर्ष पर सिर्फ परत है। तो एक एंकर टैग पर 'क्लिक' घटना को ट्रिगर करने के लिए लिंक का पालन न करें। इसके बजाय आप jquery-simulate जैसी लाइब्रेरी का उपयोग कर सकते हैं जो आपको देशी ब्राउज़र इवेंट लॉन्च करने की अनुमति देगा।

इसके बारे में अधिक विवरण इस लिंक में पाया जा सकता है


1

एक अन्य उपाय यह है कि ईवेंट श्रोता में window.setTimeout का उपयोग करें और ईवेंट की प्रक्रिया समाप्त होने के बाद कोड निष्पादित करें। कुछ इस तरह...

window.setTimeout(function() {
  // do your thing
}, 0);

मैं उस अवधि के लिए 0 का उपयोग करता हूं क्योंकि मुझे इंतजार करने की परवाह नहीं है।


1

मुझे पता है कि यह विषय पुराना है लेकिन मुझे लगता है कि मैं इसमें योगदान दे सकता हूं। यदि आप पहले से ही उस व्यवहार को जानते हैं तो आप किसी विशिष्ट तत्व पर किसी भी समय किसी ईवेंट के डिफ़ॉल्ट व्यवहार को ट्रिगर कर सकते हैं। उदाहरण के लिए, जब आप रीसेट बटन पर क्लिक घटना को ट्रिगर करते हैं, तो आप वास्तव में रीसेट फ़ंक्शन को डिफ़ॉल्ट रूप में निकटतम रूप में कॉल करते हैं। अपने हैंडलर फ़ंक्शन में, preventDefault फ़ंक्शन का उपयोग करने के बाद, आप अपने हैंडलर कोड में कहीं भी निकटतम फ़ंक्शन पर रीसेट फ़ंक्शन को कॉल करके डिफ़ॉल्ट व्यवहार को याद कर सकते हैं।


0

यदि यह उदाहरण मदद कर सकता है, तो कुछ लिंक्स पर "कस्टम पुष्टिकरण पॉपिन" जोड़ता है (मैं "$ .ui.odal.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();
            }
        );
    }
);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.