ক্লিক ইভেন্টটি ইতিমধ্যে আবদ্ধ কিনা তা যাচাই করবেন - জিকুয়েরি


130

আমি একটি ক্লিক ইভেন্ট একটি বোতামের সাথে আবদ্ধ করছি:

$('#myButton').bind('click',  onButtonClicked);

একটি triggerদৃশ্যে, এটি একাধিকবার কল করা হচ্ছে , তাই যখন আমি একটি করি তখন আমি একাধিক এজাক্স কল দেখতে পাই যা আমি প্রতিরোধ করতে চাই।

আমি bindযদি কেবল এটির আগে আবদ্ধ না হই ।


1
ম্যান, আমি মনে করি + + কনরাড Garus সবচেয়ে নিরাপদ anwser (হয়েছে stackoverflow.com/a/6930078/842768 ), আপনার গৃহীত উত্তর পরিবর্তন করতে পারেন। চিয়ার্স! আপডেট: চেক + হারবার্ট পিটারস এর মন্তব্য হিসাবে! এটাই সেরা পন্থা।
জিওভান্নিপ্ডস

বর্তমান মানের জন্য, (নিচে @A মোরেল এর উত্তর দেখার stackoverflow.com/a/50097988/1163705 )। কোডিং কম হয় এবং সমীকরণের বাইরে থাকা সমস্ত অনুমানের কাজ, অ্যালগরিদম এবং / অথবা বিদ্যমান উপাদানগুলির সন্ধান করে।
Xandor

উত্তর:


117

24 আগস্ট '12 আপডেট করুন : jQuery 1.8 এ, ব্যবহার করে উপাদানটির ইভেন্টগুলি অ্যাক্সেস করা আর সম্ভব নয় .data('events')। ( বিশদগুলির জন্য এই বাগটি দেখুন )) jQuery._data(elem, 'events')একটি অভ্যন্তরীণ ডেটা কাঠামো দিয়ে একই ডেটা অ্যাক্সেস করা সম্ভব , যা অনিবন্ধিত এবং অতএব 100% স্থিতিশীল থাকার গ্যারান্টিযুক্ত নয়। এটি অবশ্য সমস্যা হওয়া উচিত নয় এবং উপরের প্লাগইন কোডের প্রাসঙ্গিক লাইনটি নিম্নলিখিতটিতে পরিবর্তন করা যেতে পারে:

var data = jQuery._data(this[0], 'events')[type];

jQuery ইভেন্টগুলি ডাকা একটি ডেটা অবজেক্টে সংরক্ষণ করা হয় events, যাতে আপনি এটি অনুসন্ধান করতে পারেন:

var button = $('#myButton');
if (-1 !== $.inArray(onButtonClicked, button.data('events').click)) {
    button.click(onButtonClicked);
}

অবশ্যই সেরা হবে যদি আপনি নিজের অ্যাপ্লিকেশনটি কাঠামো করতে পারতেন তবে এই কোডটি কেবল একবার কল করা হবে।


এটি একটি প্লাগইনে আবদ্ধ হতে পারে:

$.fn.isBound = function(type, fn) {
    var data = this.data('events')[type];

    if (data === undefined || data.length === 0) {
        return false;
    }

    return (-1 !== $.inArray(fn, data));
};

আপনি তখন কল করতে পারেন:

var button = $('#myButton');
if (!button.isBound('click', onButtonClicked)) {
    button.click(onButtonClicked);
}

10
সম্পাদনার জন্য +1। আজ এই পোস্টটি পড়া এবং আমি ব্যবহার করছি 1.8। ধন্যবাদ.
Gigi2m02

2
সম্পাদনার জন্য ধন্যবাদ। এটি কি কেবল বোতামের জন্য বা আমিও এটি ব্যবহার করতে পারি <a>? কারণ যখন আমি চেষ্টা করি jQuery._data()তখন নিম্নলিখিত ত্রুটিতে বলেTypeError: a is undefined
Houman

আমি var data = jQuery._data(this[0], 'events')[type];চেষ্টা করে লাইনটি মুড়ে ফেলতাম এবং ক্যাশে মিথ্যা ফিরতাম। কোনও প্রকারের [0] এর সাথে আবদ্ধ না হলে [টাইপ] কল করার ফলে "অপরিজ্ঞাত বা নাল রেফারেন্সের সম্পত্তি 'ক্লিক করতে' অক্ষম" এবং স্পষ্টতই এটি আপনাকে জানাতে হবে যা আপনাকে জানায় "এর কিছু প্রকারভেদ ঘটায়।
রব ভানদাভীর

আমি নিশ্চিত না যে _ডাটা অবজেক্টটি jQuery 2.0.3 এ পরিবর্তিত হয়েছে তবে আমি এর জন্য $ .আরআর ব্যবহার করতে পারিনি। আপনি যে ফাংশনটি তুলনা করতে চান তা হ্যান্ডলারের নামক প্রতিটি ডেটা আইটেমের একটি বৈশিষ্ট্যে property আমি এটিকে স্টেটমেন্টের জন্য একটি সাধারণ ব্যবহার করতে সংশোধন করেছি এবং স্ট্রিং ইক্যুয়ালিটির জন্য যাচাই করেছি, আমি অ্যারে যা করেছি তা অনুমান করি। for (var i = 0; i < data.length; i++) { if (data[i].handler.toString() === fn.toString()) { return true; } }
রব ভানদাভীর

আপনার আপডেট / সম্পাদনা শীর্ষে কেন সরানো হচ্ছে না? ... এটি আসল সঠিক উত্তর।
ডন

179

আরও একটি উপায় - একটি সিএসএস শ্রেণি এবং ফিল্টার সহ এই জাতীয় বোতামগুলি চিহ্নিত করুন:

$('#myButton:not(.bound)').addClass('bound').bind('click',  onButtonClicked);

সাম্প্রতিক jQuery এর সংস্করণ প্রতিস্থাপন bindসঙ্গে on:

$('#myButton:not(.bound)').addClass('bound').on('click',  onButtonClicked);

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

1
গৃহীত উত্তরে যেমন বলা হয়েছিল: "অবশ্যই ভাল হবে যদি আপনি নিজের অ্যাপ্লিকেশনটি গঠন করতে পারেন তবে এই কোডটি কেবল একবার কল করা হবে।" এটি এটি সম্পাদন করে।
জেফ দেগে

আমার পরিস্থিতিতে +1, অফ / অন এবং বাইন্ড / আনবাইন্ড একাধিক কলকে আটকাতে পারে। এটিই কাজ করেছিল সমাধান।
জে

2
এটি পারফরম্যান্সের জন্য আরও ভাল সমাধান কারণ কোডটি সিএসএস শ্রেণির উপস্থিতি এবং ইতিমধ্যে উপস্থিত স্লিপ বাইন্ডিংয়ের জন্য পরীক্ষা করতে পারে। অন্যান্য সমাধান আরও ওভারহেড (কমপক্ষে fr4om আমি যা বলতে পারি) এর সাথে একটি আনবাইন্ড-তারপরে-রিবাইন্ড প্রক্রিয়া চালায়।
ফিল নিকোলাস 21

1
2 ইস্যু। (এটি কোনও প্লাগ-ইন ব্যবহার করার সময় যা বেশ কয়েকটি উপাদানের সাথে আবদ্ধ হতে পারে) উইন্ডো অবজেক্টে পুনরায় আকারের ইভেন্টটিকে বাঁধাইয়ের সময় কাজ করবে না। অ্যাডক্লাসের পরিবর্তে ডেটা ('আবদ্ধ', 1) ব্যবহার করুন ('আবদ্ধ') এটির অন্য একটি পদ্ধতি যা কাজ করে। ইভেন্টটি ধ্বংস করার সময় এটি অন্যান্য দৃষ্টান্তগুলি নির্ভর করে এমনটি করতে পারে। সুতরাং অন্যান্য দৃষ্টান্তগুলি এখনও ব্যবহারে আছে কিনা তা পরীক্ষা করা বাঞ্ছনীয়।
হারবার্ট পিটারস

59

JQuery 1.7+ ব্যবহার করা হয়:

আপনি কল করতে পারেন off আগেon :

$('#myButton').off('click', onButtonClicked) // remove handler
              .on('click', onButtonClicked); // add handler

যদি না:

আপনি এটি প্রথম ইভেন্টটি আনবাইন্ড করতে পারেন:

$('#myButton').unbind('click', onButtonClicked) //remove handler
              .bind('click', onButtonClicked);  //add handler

1
এটি ঠিক একটি সুদৃশ্য সমাধান নয়, কিন্তু এটি শুধুমাত্র একটি হ্যান্ডলার unbinding দ্বারা উন্নত করা হবে: .unbind('click', onButtonClicked)ম্যানুয়ালটি দেখুন
একাকী দিন

16
আপনি আপনার হ্যান্ডলারগুলি যুক্ত করার সাথে সাথে প্রকৃতপক্ষে নাম স্থান দিতে পারেন, তবে আনবাইন্ডিং বেশ সহজ হয়ে যায়। $(sel).unbind("click.myNamespace");
মার্ক

@ একাকী দিনটি কি 'আনবাইন্ড' ব্যবহার করে অন্যরকম কিছু দেখানোর উদ্দেশ্যে ব্যবহৃত হয়েছিল? .উনবাইন্ড কার্যকরভাবে ওফের মতো নয় তাই আপনাকে লিখতে হবে$('#myButton').unbind('click', onButtonClicked).bind('click', onButtonClicked);
জিম

1
@ জিম আপনি দেখতে পাবেন প্রশ্নটি আমার মন্তব্যের তিন বছর পরে সম্পাদিত হয়েছিল! (এবং আমার মন্তব্যের অব্যবহিত কয়েক মিনিটের মধ্যেই I আমি যে বিষয়বস্তু নিয়ে মন্তব্য করছি সেটির অস্তিত্ব নেই, যার কারণেই সম্ভবত এটি তেমন কোনও বোধগম্য মনে হয় না))
একাকী

@ লোনসমেডে হিএমএম আমি নিশ্চিত না কেন এটি সম্পাদনা করা হয়েছিল, আপনি কি ভাবেন যে আমার রোলব্যাক করা উচিত?
নফতালি ওরফে নীল

8

আমি দেখতে সবচেয়ে ভাল উপায় হ'ল লাইভ () বা প্রতিনিধি () ব্যবহার করে পিতা-মাতার ইভেন্টটি ক্যাপচার করতে এবং প্রতিটি সন্তানের উপাদানগুলিতে নয়।

যদি আপনার বোতামটি # সন্তানের মধ্যে থাকে তবে আপনি প্রতিস্থাপন করতে পারেন:

$('#myButton').bind('click', onButtonClicked);

দ্বারা

$('#parent').delegate('#myButton', 'click', onButtonClicked);

এমনকি যদি এই কোডটি কার্যকর করা হয় তখন # মাইবাটন এখনও উপস্থিত না থাকে।



8

আমি "একবার" নামে একটি খুব ছোট প্লাগইন লিখেছিলাম যা এটি করে। উপাদানটিতে চালিয়ে যান এবং চালিয়ে যান।

$.fn.once = function(a, b) {
    return this.each(function() {
        $(this).off(a).on(a,b);
    });
};

এবং সহজভাবে:

$(element).once('click', function(){
});

9
.one () প্রথম নির্বাহের পরে হ্যান্ডলারটি ফেলে দেবে।
রডল্ফো জোর্হে নিমের নোগুইরা

3
এখানে "একবার" হ্যান্ডলারটি একবার সংযুক্ত করার জন্য। jquery এ "এক" একবার চালানোর জন্য যা একবার সংযুক্ত হয় না।
শিশির অরোরা

1
আমি জানি আমি বাস্তবের পরে আসছি, তবে offপ্রদত্ত ধরণের সমস্ত হ্যান্ডলারগুলি সরাবে না ? মানে যদি কোনও পৃথক ক্লিক হ্যান্ডলারটি সম্পর্কিত না হয় তবে একই আইটেমটিতে থাকে, তবে এটিও কি সরানো হবে না?
Xandor

ইভেন্টে কেবল একটি নেমস্পেস ব্যবহার করুন যাতে এটি সমস্ত হ্যান্ডলারের মতো না পড়ে: 'কীপআপ.টেষ্ট 123'
সিমেন্টিক

6

কেন এই ব্যবহার করবেন না

unbind() আগে bind()

$('#myButton').unbind().bind('click',  onButtonClicked);

1
$('#myButton').off().on('click', onButtonClicked);আমার জন্য কাজ করে।
বীরক্রণ সেরেরুরুংগকুল

আমার জন্য কাজ করে ... gr8 সমাধান
immadhusen

সুন্দর। ইতিমধ্যে আবদ্ধ একটি বোতামের জন্য আমার পক্ষে পুরোপুরি কাজ করে।
সানব্রডেন

3

আমার সংস্করণটি এখানে:

Utils.eventBoundToFunction = function (element, eventType, fCallback) {
    if (!element || !element.data('events') || !element.data('events')[eventType] || !fCallback) {
        return false;
    }

    for (runner in element.data('events')[eventType]) {
        if (element.data('events')[eventType][runner].handler == fCallback) {
            return true;
        }

    }

    return false;
};

ব্যবহার:

Utils.eventBoundToFunction(okButton, 'click', handleOkButtonFunction)

2

@ কনরাড-গারুস উত্তরের ভিত্তিতে, তবে ব্যবহার করা data, যেহেতু আমার বিশ্বাস classবেশিরভাগ স্টাইলিংয়ের জন্য ব্যবহার করা উচিত।

if (!el.data("bound")) {
  el.data("bound", true);
  el.on("event", function(e) { ... });
}

2

চেক / বাঁধাই / আনবাইন্ড এড়ানোর জন্য, আপনি আপনার পদ্ধতির পরিবর্তন করতে পারেন! আপনি Jquery .on () ব্যবহার করবেন না কেন?

যেহেতু জ্যাকারি 1.7, .লাইভ (), .delegate () অবমূল্যায়ন করা হয়েছে, এখন আপনি .on () ব্যবহার করতে পারেন

বর্তমান এবং বর্তমানে ভবিষ্যতে নির্বাচকদের সাথে মেলে এমন সমস্ত উপাদানগুলির জন্য ইভেন্ট হ্যান্ডলার সংযুক্ত করুন

এর অর্থ হ'ল আপনি এমন একটি ইভেন্টটিকে কোনও পিতামাতার সাথে সংযুক্ত করতে পারেন যা এখনও বিদ্যমান রয়েছে এবং শিশুরা উপস্থিত থাকুক বা না থাকুক উপাদানগুলিকে সংযুক্ত করতে পারে!

আপনি যখন .on () এর মতো ব্যবহার করেন:

$('#Parent').on('click', '#myButton'  onButtonClicked);

আপনি পিতামাতাকে ইভেন্ট ক্লিক করুন এবং এটি উপস্থিত থাকলে শিশু '# মাই বাটন' অনুসন্ধান করুন ...

সুতরাং আপনি যখন কোনও শিশু উপাদান সরিয়ে বা যুক্ত করেন তখন ইভেন্টের বাইন্ডিংটি যুক্ত করতে বা মুছতে হবে কিনা তা নিয়ে আপনাকে চিন্তা করার দরকার নেই।


বর্তমান মানগুলির জন্য এটি একেবারে সেরা উত্তর। সন্তানের জন্য দেখার জন্য পিতামাতার উপর হ্যান্ডলারটি সেট করার এই বৈশিষ্ট্যটি ভালভাবে বিজ্ঞাপন করা হয়েছে তবে এটি বরং মার্জিত সমাধান। আমি একাধিকবার একটি ইভেন্টে আগুন জ্বালছিলাম এবং প্রতিবার এটি চালানো মোট পরিমাণ বাড়তে থাকে। এই একক লাইনটি পুরো কৌশলটি করেছে এবং এটি ব্যবহার না করেই .offআমি বিশ্বাস করি যে প্রক্রিয়াটিতে সম্পর্কযুক্ত হ্যান্ডলারগুলি অপসারণ করা হবে।
Xandor


0
if ($("#btn").data('events') != undefined && $("#btn").data('events').click != undefined) {
    //do nothing as the click event is already there
} else {
    $("#btn").click(function (e) {
        alert('test');
    });
}

0

জুন 2019 পর্যন্ত, আমি ফাংশনটি আপডেট করেছি (এবং এটি আমার যা প্রয়োজন তার জন্য কাজ করে)

$.fn.isBound = function (type) {
    var data = $._data($(this)[0], 'events');

    if (data[type] === undefined || data.length === 0) {
        return false;
    }
    return true;
};

-2

জিকুয়েরির সমাধান রয়েছে :

$( "#foo" ).one( "click", function() {
  alert( "This will be displayed only once." );
}); 

সমতুল্য:

$( "#foo" ).on( "click", function( event ) {
  alert( "This will be displayed only once." );
  $( this ).off( event );
});

1
আপনার উত্তর প্রশ্নের সাথে সম্পর্কিত নয়। প্রশ্নটি শুধুমাত্র একবারে ইভেন্টের ইভেন্টে বাঁধার ফাংশন সম্পর্কে।
মিশা জালেউস্কি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.