কীভাবে ইভেন্ট.প্রিভেন্টডিফল্ট () ব্যবহারের পরে কোনও ইভেন্ট ট্রিগার করবেন


155

যতক্ষণ না আমি এটি চালাতে প্রস্তুত না হওয়া পর্যন্ত আমি একটি ইভেন্ট রাখতে চাই

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

   e.preventDefault(); 

   // do lots of stuff

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

}

run()উপরে বর্ণিত কার্যটির সমতুল্য কি আছে ?


ডিফল্ট আচরণটি কেবলমাত্র আপনার হ্যান্ডলার ফিরে আসার পরে ঘটে। কেবলমাত্র আপনার হ্যান্ডলারে এটির অনুমতি দেওয়ার জন্য সেই আচরণটি প্রতিরোধ করা কিছুটা বোধগম্য নয়।
ফ্রিডরিক হামিদি

7
@ ফ্রাডেরিক হামিদি দুর্ভাগ্যক্রমে, অ্যাসিঙ্ক স্টাফ (aj .জ্যাক্স, কলব্যাকস, ইত্যাদি) ডিফল্ট আচরণ হতে দেবে।
ভিজউইক

উত্তর:


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
। লাইভ চিত্রিত হয়। নীচে @ কোরি ড্যানিয়েলসনের উদাহরণে .on ব্যবহার করুন।
nwolybug

এই আবার ভিতরে .click হচ্ছে এবং অবশেষে আমি দেখুন "অত্যধিক পুনরাবৃত্তির"
হিমাংশু পাঠক

5
@ হিমাংশু পাঠক - আপনি সম্ভবত lots_of_stuff_already_done = true;পতাকাটি স্থাপন করতে ভুলে গেছেন - অন্যথায় ফাংশনটির পুনরাবৃত্তি চালানোর কোনও উপায় নেই।
ভিজউইক

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 */
    }

});



এর মতো কোনও কিছুর জন্য ভাল ব্যবহারের ক্ষেত্রে আপনার লিগ্যাসি ফর্ম কোডটি কার্যকর হতে পারে তবে ফর্মটি জমা দেওয়ার আগে আপনাকে ইমেল ঠিকানার বৈধতার মতো কিছু যুক্ত করে ফর্মটি বাড়ানোর জন্য বলা হয়েছে। ব্যাক-এন্ড ফর্ম পোস্ট কোডটি খনন করার পরিবর্তে, আপনি একটি এআইপি লিখতে পারেন এবং তারপরে frontতিহ্যবাহী পোষ্টটি করার অনুমতি দেওয়ার আগে প্রথমে সেই API এ আঘাত করতে আপনার ফ্রন্ট-এন্ড কোড আপডেট করতে পারেন update

এটি করতে, আপনি এখানে যা লিখেছেন তার অনুরূপ কোডটি আপনি প্রয়োগ করতে পারেন:

$('#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 এ কার্যকর হবে বলে মনে হচ্ছে না; (
জোনবি

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

আইএমএইচও, ঠিক একই ডেটা দিয়ে ইভেন্টটিকে পুনরায় চালিত করার এটি সবচেয়ে সম্পূর্ণ উপায় complete


eঅনির্ধারিত. হওয়া উচিত evt.preventDefault()। আমি সম্পাদনা করার চেষ্টা করেছি, তবে আমার সম্পাদনাগুলি> characters টি অক্ষর হতে হবে এবং আমি সবেমাত্র 2 :(
কেভঙ্ক

3
@ কেভনক, আমি সাধারণত একটি লাইন মন্তব্য আকারে সম্পাদনার সংক্ষিপ্ত বিবরণ অন্তর্ভুক্ত করি। এটি জমা দেওয়া চরিত্রের সংখ্যা বাড়ানো উচিত।
recurse

কেন জানি না কেন এই উত্তরটি বেশি উত্সাহিত করা হয়নি, এটি সত্যই কার্যকর। প্রচারের সাথে কাজও বন্ধ হয়ে যায় event.isPropagationStopped = function(){ return false; };। আমি ইভেন্টটিতে একটি কাস্টম সম্পত্তিও যুক্ত করেছি যাতে হ্যান্ডলারের মধ্যে আমি সনাক্ত করতে পারি যে যদি চেকটি ক্রিয়াকলাপটি রোধ করে তাই করা হয়েছে যাতে এটি আর না করা হয়। গ্রেট!
কদ্দাথ

আমি বুটস্ট্র্যাপ 4 টি ট্যাব ব্যবহার করেছি, এটি পুরোপুরি সূক্ষ্মভাবে কাজ করেছে। অনেক ধন্যবাদ. '(' # ভি-পিলস-ট্যাব এ ')। (' ক্লিক ', ফাংশন (ঙ) {ই.প্রিভেন্টডাফল্ট (); সেটটাইমআউট (ফাংশন ()) '# ভি-পিলস-হোম-ট্যাব') on ('দেখানো। বিএসএটিব', ফাংশন () {$ ('। মেইনড্যাশবোর্ড')। শো (); # ('# চেঞ্জপ্ল্যান')। লুকান)) (); });}, 1000); $ (এটি) .টিব ('শো');});
সূর্য আর প্রবীণ

8

এটা ব্যবহার করা সম্ভব currentTargetএর event। উদাহরণ দেখায় যে কীভাবে ফর্ম জমা দিতে হবে। একইভাবে আপনি onclickবৈশিষ্ট্য ইত্যাদি থেকে ফাংশন পেতে পারেন

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

  // code

  event.currentTarget.submit();
});

জমা দেওয়া কোনও বৈধ ফাংশন নয়
দেবফায়ের

যদি আপনি submit()একই উপাদানটিকে কল করেন, আপনি কি আপনার `` $ ('ফর্ম')। ('জমা') কোডটিতে ফিরে আসবেন না এবং বারবার এটি আবার করবেন?
ফ্যানি ভয়েড

7

e.preventDefault();শর্তযুক্তভাবে কেবল সম্পাদন করবেন না , বা সম্পাদন করবেন না ।

আপনি অবশ্যই পরিবর্তন করতে পারবেন না যখন আসল ইভেন্ট কর্ম ঘটে।

আপনি যদি কিছু সময়ের পরে আসল UI ইভেন্টটি "পুনরায় তৈরি" করতে চান (বলুন, একটি এজেএক্স অনুরোধের কলব্যাকে) তবে আপনাকে এটি অন্য কোনও উপায়ে নকল করতে হবে (যেমন ভিজউইকের উত্তরে) ... যদিও আমি চাই যেমন একটি পদ্ধতির ব্যবহারযোগ্যতা প্রশ্ন।



3

যতক্ষণ না "প্রচুর স্টাফ" অ্যাসিঙ্ক্রোনাস কিছু না করে এটি একেবারেই অনিবার্য - ইভেন্টটি প্রতিটি হ্যান্ডলারকে ধারাবাহিকভাবে ডেকে আনে, সুতরাং যদি কোনও প্যারেন্ট-এলিমেন্টে একটি অন্লিক-ইভেন্ট হয় তবে এটি অনক্লিকের পরে গুলি ছোঁড়াবে- সন্তানের ইভেন্ট সম্পূর্ণ প্রক্রিয়া করা হয়েছে। জাভাস্ক্রিপ্ট এখানে কিছু ধরণের "মাল্ট্রিথ্রেডিং" করে না যা ইভেন্ট প্রসেসিংকে "স্টপিং" করে তোলে। উপসংহার: একটি ইভেন্ট কেবল একই হ্যান্ডেলারে পুনরায় শুরু করার জন্য "বিরতি" দেওয়ার কোনও মানে হয় না।

যদি "উপাদান প্রচুর" হয় এই অ্যাসিঙ্ক্রোনাস কিছু এছাড়াও অর্থে দেখা যায় না যেমন asynchonous জিনিষ বাধা দেয় তারা কি করা উচিত (asynchonous কাপড়) এবং তাদের bahave করা মত সবকিছু ক্রমানুসারে আছে (যেখানে আমরা আমার প্রথম অনুচ্ছেদে ফিরে আসা করতে )


মাঝখানে প্রক্রিয়াটি অবিচ্ছিন্ন, আমি এজ্যাক্স কলব্যাকের ফলাফলটি ছড়িয়ে দিতে চাই ...
মাজেটেক

1
যদি আপনাকে এজ্যাক্স-অনুরোধটির জন্য এটি সিঙ্কনাস করে তুলতে হয় (জ্যাকোরির জন্য, async-fag: api.jquery.com/jQuery.ajax ) ... তবে সিঙ্কনাস এজ্যাক্স-অনুরোধ করা প্রায় প্রতিটি ক্ষেত্রেই একটি খারাপ ধারণা, সুতরাং এটির চেয়ে আলাদা সমাধান বের করা ভাল।
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()। Thats কারণ jQuery দ্বারা উত্পাদিত ক্লিক ইভেন্টটি দেশীয় ব্রাউজার ইভেন্টগুলির শীর্ষে রয়েছে। সুতরাং অ্যাঙ্কর ট্যাগটিতে একটি 'ক্লিক' ইভেন্টটি ট্রিগার করা লিঙ্কটি অনুসরণ করবে না। পরিবর্তে আপনি jquery- সিমুলেটের মতো একটি লাইব্রেরি ব্যবহার করতে পারেন যা আপনাকে ব্রাউজার ইভেন্টগুলি নেটিভ করতে দেয়।

এই সম্পর্কে আরও বিশদ এই লিঙ্কে পাওয়া যাবে


1

আরেকটি সমাধান হ'ল ইভেন্ট শ্রোতার মধ্যে উইন্ডো.সেটটাইমআউট ব্যবহার করা এবং ইভেন্টটির প্রক্রিয়া শেষ হওয়ার পরে কোডটি কার্যকর করা। কিছুটা এইরকম...

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

আমি পিরিয়ডের জন্য 0 ব্যবহার করি যেহেতু আমি অপেক্ষা করার বিষয়ে চিন্তা করি না।


1

আমি জানি এই বিষয়টি পুরানো তবে আমি মনে করি আমি অবদান রাখতে পারি। আপনি যদি আগে থেকেই সেই আচরণটি জানেন তবে আপনার হ্যান্ডলার ফাংশনটিতে যে কোনও সময় আপনি কোনও নির্দিষ্ট উপাদানের কোনও ইভেন্টের ডিফল্ট আচরণটি ট্রিগার করতে পারেন। উদাহরণস্বরূপ, আপনি যখন রিসেট বোতামে ক্লিক ইভেন্টটি ট্রিগার করেন, আপনি আসলে নিকটতম ফর্মটিতে রিসেট ফাংশনটিকে ডিফল্ট আচরণ হিসাবে কল করেন। আপনার হ্যান্ডলারের ফাংশনে, প্রতিরোধক ডিফল্ট ফাংশনটি ব্যবহার করার পরে, আপনি আপনার হ্যান্ডলার কোডের যে কোনও জায়গায় নিকটতম ফর্মটিতে রিসেট ফাংশনটি কল করে ডিফল্ট আচরণটি স্মরণ করতে পারেন।


0

এই উদাহরণটি যদি সহায়তা করতে পারে তবে কিছু লিঙ্কগুলিতে একটি "কাস্টম কনফার্ম পপিন" যুক্ত করুন (আমি "ui .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();
            }
        );
    }
);
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.