javascript - 如何使onclick函數只執行一次?




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>

事件處理程序和監聽器

將事件註冊到元素有三種方法*。 以下示例顯示如何將click事件註冊到具有類 .once **的鏈接,該類在觸發時調用函數 test()

  1. 事件監聽器(推薦)
    • document.querySelector('.once') addEventListener('click',test); `
  2. 事件屬性( 推薦)
    • <a href='#/' class='once' >Click</a>
  3. 活動財產
    • document.querySelector('.once') onclick = test; `

* 有關 詳細信息, 請參閱 DOM事件處理程序
** .once 類與#2無關

問題

OP O riginal P ost)有一個事件監聽器(參見上面的#1)向 <body> 標籤註冊一個click事件,並將一個on-event屬性(見上面的#2)註冊到 <div> 。 每個人都調用一個名為 klikaj() 的函數(也稱為回調函數 klikaj() ,這是多餘的。 當您打算讓用戶單擊div時,單擊正文(通常在任何地方)都沒有用。 如果用戶點擊 除div klikaj() 任何地方,將調用 klikaj() 。 如果用戶單擊div, klikaj() 將被調用兩次。 我建議您刪除兩個事件處理程序並將其替換為:

一個。

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

請注意, klikaj 沒有括號 () 因為瀏覽器解釋 () 現在運行函數而不是用戶觸發註冊事件時(參見上面的#1和#3)。 如果事件處理程序具有其他語句和/或回調函數,則應將匿名函數包裝在其中並應用正常語法:

B.

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

更簡潔的替代方法是在回調函數的定義中添加額外的行,並註冊#A等事件。

只需將以下語句添加為 klikaj() 的最後一行:

this.style.pointerEvents = "none";

這將使點擊的標籤無法點擊。 應用於OP代碼應該是這樣的:

<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 - 註冊到click事件的普通鏈接,當觸發時調用 test()

  2. .once - 註冊到click事件的鏈接,當觸發時調用 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>


你可以像這樣使用 removeAttribute()document.getElementById('thumb0').removeAttribute("onclick");

或者你可以讓函數像這樣返回false: document.getElementById('thumb0').onclick = ()=> false


只需使用一個標誌變量並在第一次執行時設置它:

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>


如果希望僅在用戶單擊按鈕時調用該函數,則必須從正文中刪除click事件偵聽器。

只有在功能體本身內部更改klikaj的功能定義後才能激活gtag功能。 第一次調用後,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>

我建議設置變量並檢查其值。

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

或者按照其他人的建議刪除onclick事件,

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

請注意, once: true 遺憾的是,IE和Edge不支持 once: true 。 請參閱 MDN







dom-events