javascript - ऑन्कलिक फ़ंक्शन को केवल एक बार कैसे निष्पादित करें?




html dom-events (5)

मेरे पास एक बटन पर Google विश्लेषिकी के लिए यह कोड है। मुझे इसे केवल एक बार निष्पादित करने की आवश्यकता है, ताकि उपयोगकर्ता कई बार बटन दबाकर आंकड़े नहीं बदल सके। मैंने इसी तरह के विषयों से समाधान की कोशिश की, लेकिन वे काम नहीं करते हैं। कृपया मदद कीजिए। यह मेरा कोड है।

<script>
    function klikaj(i) {
        gtag('event', 'first-4', {
            'event_category' : 'cat-4',
            'event_label' : 'site'
        });
    }

    document.body.addEventListener("click", klikaj(i), {once:true})
</script>


<div id="thumb0" class="thumbs" onclick="klikaj('rad1')">My button</div>

इवेंट हैंडलर और श्रोता

एक घटना को एक तत्व को पंजीकृत करने के तीन तरीके हैं *। निम्न उदाहरण दिखाते हैं कि क्लिक इवेंट को क्लास के साथ लिंक से कैसे रजिस्टर किया .once ** ** जो ट्रिगर होने पर फ़ंक्शन test() कॉल करता है।

  1. घटना श्रोता (अनुशंसित)
    • document.querySelector('.once') .addventventListener ('क्लिक', परीक्षण); `
  2. ऑन-इवेंट विशेषता (अनुशंसित नहीं )
    • <a href='#/' class='once' onclick='test()'> >Click</a>
  3. घटना पर संपत्ति
    • document.querySelector('.once') .onclick = परीक्षण; `

* विवरण के लिए डोम ऑन-ईवेंट हैंडलर देखें
** .once क्लास # 2 के लिए प्रासंगिक नहीं है

मुद्दे

ओपी ( रिगिनल पी ओस्ट) में एक इवेंट श्रोता (# 1 ऊपर देखें) पर क्लिक इवेंट रजिस्टर करने के लिए <body> टैग और ऑन-ईवेंट विशेषता (# 2 ऊपर देखें) पर क्लिक इवेंट रजिस्टर करके <div> । प्रत्येक व्यक्ति klikaj() नाम से एक फ़ंक्शन (उर्फ कॉलबैक फ़ंक्शन) को कॉल करता है, जो बेमानी है। जब आप उपयोगकर्ता को एक div क्लिक करने का इरादा रखते हैं तो शरीर पर क्लिक करना (जो कि हर जगह सामान्य रूप से होता है) उपयोगी नहीं है। क्या उपयोगकर्ता को कहीं भी क्लिक करना चाहिए लेकिन div , klikaj() कहा जाएगा। क्या उपयोगकर्ता को div पर क्लिक करना चाहिए, klikaj() को दो बार कहा जाएगा। मेरा सुझाव है कि आप दोनों ईवेंट हैंडलर को हटा दें और उन्हें इसके साथ बदलें:

ए।

document.getElementById('thumb0').addEventListener("click", klikaj);

ध्यान दें कि klikaj का कोई कोष्ठक () नहीं है क्योंकि ब्राउज़र उपयोगकर्ता को पंजीकृत घटना को ट्रिगर करने के बजाय अब फ़ंक्शन को चलाने के लिए () व्याख्या करता है () ऊपर # 1 और # 3 देखें)। यदि किसी इवेंट हैंडलर के पास अतिरिक्त कथन और / या कॉलबैक फ़ंक्शन हैं, तो एक अनाम फ़ंक्शन को इसके चारों ओर लपेटा जाना चाहिए और सामान्य सिंटैक्स लागू होता है:

बी

document.getElementById('thumb0').addEventListener("click", function(event) { 
  klikaj();
  console.log('clicked');
});

एक क्लीनर विकल्प कॉलबैक फ़ंक्शन की परिभाषा में अतिरिक्त लाइनों को जोड़ने और # ए जैसी घटनाओं को पंजीकृत करने के लिए है।

उपाय

बस निम्न कथन को klikaj() की अंतिम पंक्ति के रूप में klikaj() :

this.style.pointerEvents = "none";

यह क्लिक किए गए टैग को अयोग्य घोषित कर देगा। ओपी कोड पर लागू यह इस तरह होना चाहिए:

<div id="thumb0" class="thumbs">Thumb 0</div>
<script>
  function klikaj(event) {
    gtag('event', 'first-4', {
      'event_category' : 'cat-4',
      'event_label' : 'site'
    });
    this.style.pointerEvents = "none";   
  }

  document.getElementById('thumb0').addEventListener("click", klikaj);
</script>

डेमो

निम्नलिखित डेमो में दो लिंक हैं:

  1. .default - क्लिक ईवेंट के लिए पंजीकृत सामान्य लिंक जो ट्रिगर कॉल test()

  2. .once - क्लिक ईवेंट के लिए पंजीकृत एक लिंक जो ट्रिगर कॉल test() शुरू होने पर लिंक को लिंक नहीं करता है।

function test() {
  console.log('test');
}

document.querySelector('.default').onclick = function(e) {
  test();
}

document.querySelector('.once').onclick = function(e) {
  test();
  this.style.pointerEvents = 'none';
}
<a href='#/' class='default'>Default</a><br>
<a href='#/' class='once'>Once</a>


अपने बटन पर onclick विशेषता निकालें और श्रोता को जावास्क्रिप्ट के माध्यम से पंजीकृत करें, जैसा कि आपने करने की कोशिश की:

<div id="thumb0" class="thumbs"
  style="border: 1px solid; cursor: pointer; float: left">
    My button
</div>
<script>
    function klikaj(i) {
        console.log(i);
    }
    document.getElementById('thumb0')
        .addEventListener("click", function(event) {
            klikaj('rad1');
        }, {once: true});
</script>

यदि आपका ब्राउज़र { once: true } विकल्प का समर्थन नहीं करता है, तो आप ईवेंट श्रोता को मैन्युअल रूप से निकाल सकते हैं:

<div id="thumb0" class="thumbs"
  style="border: 1px solid;cursor: pointer;float:left">
    My button
</div>

<script>
    function klikaj(i) {
        console.log(i);
    }
    function onClick(event) {
      klikaj('rad1');
      document
        .getElementById('thumb0')
        .removeEventListener("click", onClick);
    }
    
    document
      .getElementById('thumb0')
      .addEventListener("click", onClick);
</script>


जिस तरह से आप अपने हैंडलर फ़ंक्शन को संलग्न करने का प्रयास कर रहे हैं, उसके साथ एक समस्या है। फ़ंक्शन klikaj(i) undefined देता है ताकि आप बटन पर अपरिभाषित संलग्न कर रहे हैं। यदि आप बटन क्लिक करने पर klikaj(i) निष्पादित करना चाहते हैं, तो इसे इस तरह से एक क्लोजर के अंदर रखें:

const button = document.querySelector('button')
const i = 10
function klikaj(i) {console.log('clicked once')}

button.addEventListener('click', () => { klikaj(i) }, {once: true})
<button>Hello world</button>

यदि ब्राउज़र {once: true} समर्थन नहीं करता है, तो आप इसका उपयोग करके अनुकरण कर सकते हैं:

const button = document.querySelector('button')
const i = 10
function klikaj(i) {console.log("clicked once")}

function clickOnceHandler(event) {
  klikaj(i)
  event.currentTarget.removeEventListener('click', clickOnceHandler)
}

button.addEventListener('click', clickOnceHandler)
<button>Hello world</button>


बस एक ध्वज चर का उपयोग करें और इसे पहले निष्पादन पर सेट करें:

var handlerExecuted = false;
function clickHandler() {
  if (!handlerExecuted) {
    console.log("call gtag() here");
    handlerExecuted = true;
  } else {
    console.log("not calling gtag() function");
  }
}
document
  .getElementById("thumb0")
  .addEventListener("click", clickHandler);
<div id="thumb0" class="thumbs">My button</div>

एक अग्रिम भिन्नता जो क्लोजर का उपयोग करती है और कई बटन पर उपयोग की जा सकती है:

function clickHandlerFactory() {
  var handlerExecuted = false;
  return function() {
    if (!handlerExecuted) {
      console.log("call gtag() here");
      handlerExecuted = true;
    } else {
      console.log("not calling gtag() function");
    }
  }
}
[...document.querySelectorAll(".thumbs")].forEach(function(el) {
  el.addEventListener("click", clickHandlerFactory());
});
<div id="thumb0" class="thumbs">Button 1</div>
<div id="thumb1" class="thumbs">Button 2</div>


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

अपने gtag फंक्शन को केवल एक बार फायर करने के लिए, आप फंक्शन बॉडी के अंदर klikaj की फंक्शन परिभाषा को बदल सकते हैं। पहले कॉल के बाद gtag कभी नहीं कहा जाएगा।

नीचे दिया गया कोड ठीक काम करता है।

<script>
    function klikaj(i) {
        gtag('event', 'first-4', {
            'event_category' : 'cat-4',
            'event_label' : 'site'
        });
        klikaj = function() {};
    }
</script>


<div id="thumb0" class="thumbs" onclick="klikaj('rad1')">
    My button
</div>




dom-events