घटना केवल एक बार


104

मेरे पास निम्नलिखित कोड हैं:

function someMethod()
{
  $(obj).click(function {});
}

someMethod को दो बार कहा जाता है और इस प्रकार क्लिक इवेंट दो बार बंध जाता है। मैं इसे केवल एक बार कैसे बांध सकता हूं?


जवाबों:


190

आप इसे लागू कर सकते हैं, शायद पर एक नज़र ले जाना चाहते event.preventDefault और event.stopPropagation की तरह अपने विधि के भीतर या अनबाइंड और बाँध हर बार,

function someMethod()
{
  $(obj).off('click').on('click', function(e) {
    // put your logic in here 
  });
}

19
सावधान रहें, क्योंकि यह सभी क्लिक घटनाओं को अनबाइंड करता है, और यह हमेशा व्यवहार नहीं चाहता है। उदाहरण के लिए, जब आप दस्तावेज़ में किसी चीज़ को बांधते हैं, तो आप केवल उस एक घटना को रोकना चाहते हैं, उन सभी को नहीं।
मेर्तिस ब्राइडिस

26
यदि आप गलती से अन्य क्लिक की घटनाओं को अंजाम नहीं देना चाहते हैं, तो आप उपयोग करना चाहते हैं function someMethod() { $(obj).off('click.namespace').on('click.namespace', function {}); }
मनु

@ मनु आपने इस जवाब
aexl

89

Pna के उत्तर के अलावा, आप अपने ईवेंट को नाम देने के बारे में सोचना चाह सकते हैं ताकि आप सभी क्लिक इवेंट्स को सार्वजनिक रूप से अनबाइंड न करें।

फंक्शन someMethod () {
    $ (obj) .unbind ('click.namespace')। बाइंड ('click.namespace', function () {});
}

https://api.jquery.com/event.namespace/


10
यह स्वीकृत उत्तर होना चाहिए। सभी क्लिक की घटनाओं को अनबाइंड करने से चीजें आसानी से टूट सकती हैं - खासकर अगर इसका एक जटिल प्रोजेक्ट जिसमें बहुत सारे jQuery चल रहे हों। उसके लिए धन्यवाद! इस सरल नाम स्थान समाधान के बारे में पता नहीं था !!
साइमन स्टाइनबर्गर

वर्तमान jQuery के साथ, यह $(obj).off()और $(obj).on()क्रमशः होना चाहिए । अन्यथा, नाम स्थान ने मदद की और यह काम किया। धन्यवाद!
एसेक्स

19

यह निर्धारित करने के लिए कोई विधि नहीं बनाई गई है कि क्या आपने पहले से ही इस विशेष फ़ंक्शन को बांधा है। आप किसी ऑब्जेक्ट पर कई क्लिक फ़ंक्शन को बांध सकते हैं। उदाहरण के लिए:

$('#id').bind('click', function(){
alert('hello');
});


$('#id').bind('click', function(){
alert('goodbuy');
});

यदि आप उपरोक्त वस्तु पर क्लिक करते हैं तो यह हैलो को अलविदा कर देगा। यह सुनिश्चित करने के लिए कि केवल एक फ़ंक्शन क्लिक इवेंट के लिए बाध्य है, क्लिक इवेंट हैंडलर को अनबाइंड करें और फिर इस तरह से वांछित फ़ंक्शन को बांधें:

$(obj).unbind('click').bind('click', function(){... });

12

स्पष्ट समाधान someMethod()दो बार फोन नहीं करना है । यदि आप इसे ठीक नहीं कर सकते हैं, तो आप एक स्टेट वैरिएबल रख सकते हैं ताकि यह केवल एक बार इस तरह से बांध सके:

function someMethod()
{
    if (!someMethod.bound) {
        $(obj).click(function() {});
        someMethod.bound = true;
    }
}

नोट: यह फ़ंक्शन की एक संपत्ति का उपयोग करता है, न कि यह बाध्य है कि क्या रखने के लिए एक वैश्विक चर को पेश करने के बजाय। आप किसी ऑब्जेक्ट का उपयोग स्वयं ऑब्जेक्ट पर भी कर सकते हैं।

आप इसे यहाँ काम कर सकते हैं: http://jsfiddle.net/jfriend00/VHkxu/


11

या jQuery के एक () फ़ंक्शन का उपयोग करें, जो चालू () के समान है, लेकिन केवल घटना को एक बार फायर करता है, भले ही आप इसे कई बार बांधें।

http://api.jquery.com/one/


8
कभी-कभी यह मदद करता है। लेकिन कभी-कभी आप ऐसा समाधान चाहते हैं जिसमें आप कर सकें: ATTACH ONCE BUT USE MANY।
रज़ासर

5

jQuery कुछ फ़ंक्शन को केवल एक बार बहुत आसान बनाना संभव बनाता है:

function someMethod()
{

     $(obj).click(function() {});
      this.someMethod = $.noop;
}

1
यह तभी काम करेगा जब someMethod किसी ऑब्जेक्ट या ग्लोबल फंक्शन का तरीका हो।
ज्यूबिक

jQuery.noopकेवल एक चरित्र से कम है function(){}, इसलिए यह थोड़े मूर्खतापूर्ण तरीके से कह रहा है कि यह "मदद" कर रहा है, बस एक खाली फ़ंक्शन प्रदान कर रहा है। यहाँ इस सामान्य समाधान का एक गैर-jQuery गैर-विधि उदाहरण है:var fn = function(){ fn = function(){}; do stuff; };
1j01

1
@ 1j01 के $बजाय उपयोग करने के लिए संपादित
Esailija

2

यह एक सुझाव है क्योंकि मैं आपके तर्क को नहीं जानता। आपके लिए काम कर सकता है या नहीं।

Jquery लाइव () और एक () फ़ंक्शन को संयोजित करने का प्रयास करें, जो आपको इवेंट रिबंड की तुलना में बेहतर परिणाम देगा।

विशेष मामले तब काम करते हैं जब आपके पास 2 DOM तत्व (माता-पिता और बच्चे) होते हैं। माता-पिता नोड पर लाइव () सुनिश्चित करता है कि घटना को लागू किया जाएगा, और फिर एक () को गतिशील रूप से रजिस्टर करने के लिए कॉल करता है जिसे केवल एक बार निष्पादित किया जाएगा। (यह रिबंड की तरह समान कार्यक्षमता प्रदान करता है)।


One()कार्य किया, chromeलेकिन इसमें काम नहीं safariकिया Mac
हाफ ब्लड प्रिंस

2

आप bssed तत्वों में css वर्ग जोड़ सकते हैं और फिर उन्हें फ़िल्टर कर सकते हैं:

function someMethod()
{
    $(obj).not('.click-binded')
          .click(function {})
          .addClass('click-binded');
}

इस विधि का उपयोग प्लगइन्स के लिए भी किया जा सकता है:

  $(obj).not('.datetimepicker-applied')
        .datetimepicker()
        .addClass('datetimepicker-applied');

1
var bound = false;

function someMethod()
{
    if(!bound)
    {
       $(obj).click(function {});
       bound = true;
    }
}

लेकिन मैं शायद इस पर गौर करूंगा कि किसी तरह का वर्कअराउंड करने से पहले दो बार क्यों बुलाया जा रहा है।


3
यदि आप इस तरह जा रहे हैं तो jfriend00 के समाधान पर विचार करें जहां वैश्विक नाम स्थान को प्रदूषित boundकरने के someMethod()बजाय संलग्न किया गया है।
9

1

यदि आप किसी वस्तु को केवल एक बार बांधना चाहते हैं, तो आपको एक ध्वज लागू करना चाहिए और उस वस्तु पर टिक जाना चाहिए।

उदाहरण के लिए:

if($('#id') && $('#id').data('done') == null)) {
    $('#id').bind('click', function() {
        alert('hello');
    });

    $('#id').data('done', true);
}

1

आप इस jQuery एक्सटेंशन फ़ंक्शन का उपयोग कर सकते हैं।

$.fn.once = function (type, fn, uid) {
  if(uid == undefined) {
    console.error("Called $.once without uid\n", this, "\n", fn);
  }

  var dataStr = type+"-handler-"+uid;
  if(!this.data(dataStr)) {
    this.data(dataStr, true);
    this.on(type, fn);
  }
};

ऐसा करने के बजाय

$("button").on("click", function(){
  alert("You Clicked On A Button");
});

हां ऐसा करो

$("button").once("click", function(){
  alert("You Clicked On A Button");
}, "btnHandler");

अब जब मेरे पास एक फंक्शन है

function addBtnHandler() {
  $("button").once("click", function() {
    alert("You Clicked On A Button");
  }, "btnHandler");
}

और मैं इसे कई बार कहता हूं

addBtnHandler();
addBtnHandler();
addBtnHandler();

यह केवल एक बार करता है।

ध्यान दें कि एक्सटेंशन यूआईडी और प्रकार दोनों की जांच करके काम करता है। इसका मतलब है कि आप एक ही यूआईडी के साथ विभिन्न प्रकार के हैंडलर बांध सकते हैं, आप ऐसा नहीं भी कर सकते हैं या नहीं कर सकते हैं। इसे बदलने के लिए संपादित करें।

var dataStr = type+"-handler-"+uid;

जैसे कुछ के साथ

var dataStr = "handler-"+uid;


1

मैं भी केवल एक बार डोम तत्व के साथ बाध्यकारी घटना के लिए बंद और jquery की विधि पर उपयोग करने की कोशिश कर रहा था जो अभी तक मौजूद नहीं है या डोम तत्व अभी तक नहीं बना है।

$('.select').off('event').on('event', 'selector', function(e){ // });

यह कोड ठीक से काम नहीं कर रहा था

मैं एक बहुत ही आकर्षक पद्धति के बारे में आया जो 'एक' विधि है। यह बहुत उपयोगी है जब आप किसी घटना को केवल एक बार बांधना चाहते हैं।

आप यहाँ दस्तावेज़ पा सकते हैं http://api.jquery.com/one/

यह 'ऑन' की विधि के समान है, लेकिन कई चयनकर्ताओं के लिए ईवेंट के साथ नहीं चिपकाने के साथ अपने व्यवहार के साथ अलग है।

$('body').one('click', 'selector', function(){ // do your stuff here });

1

आप AddEventListener विधि और उसके एक बार विकल्प का उपयोग करके, शुद्ध JS के साथ इसे प्राप्त कर सकते हैं

target.addEventListener('click', handler, {once: true});

2
यह तत्व को एक बार क्लिक करने के बाद ईवेंट अनबाउंड होने का कारण बनता है। यह कई बार बाध्य होने वाली घटनाओं की समस्या को हल नहीं करता है।
शीर्ष कैट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.