【问题标题】:How can I add an event for a one time click to a function?如何将一次单击事件添加到功能?
【发布时间】:2015-02-19 15:35:28
【问题描述】:

我想为一个函数添加一个点击事件监听器,但只希望它发生一次。我怎么能这样做?

如果可能的话,我也想远离 JQuery。

已编辑

由于我得到的答案完全满足了我的需要,我想我可以通过上下文让它更清楚一些。

我正在编写一个绘制矩形的函数,首先单击一个按钮来启动矩形函数。然后drawRectangle函数中有两个点击事件监听器。这些是我希望在函数中只发生一次的事件。允许用户在再次单击矩形启动按钮时创建另一个矩形。

【问题讨论】:

  • @antyrat OP 特别要求不要使用 jQuery。
  • 不会在开始时将布尔值设置为false,如果这是第一次,然后执行if,如果确实是第一次将其更改为true?跨度>

标签: javascript


【解决方案1】:

使用现代 JavaScript!

EventTarget.addEventListener("click", function() {

    // Do something cool

}, {once : true});

一个布尔值,表示添加后最多应调用一次侦听器。如果是true,监听器在调用时会被自动移除。

-MDN web docs

All modern browsers支持此功能

Other reference

【讨论】:

  • 仍然不能用于大多数生产站点,因为它不支持 IE11。但确实非常好!
  • + 一个。好消息,无需声明函数!谢谢。
  • 太棒了!非常简单的使用。
【解决方案2】:

一旦事件被触发一次,您必须使用removeEventListener。但是,removeEventListener 将函数作为参数,这意味着您需要声明一个命名函数,使用addEventListener 添加它,然后将其删除。示例:

function foo() {
    // do things, then
    removeEventListener('click', foo);
}

addEventListener('click', foo);

【讨论】:

  • 我一开始也忘记了这个,但是removeEventListener也需要事件类型:removeEventListener("click", foo);
  • 等等等等,removeEventListeneraddEventListener都是方法不是函数!
  • 这是一个已弃用的解决方案。见stackoverflow.com/a/46291530/2826713
【解决方案3】:
function one(el, type, fn) {
    function handler(event) {
        el.removeEventListener(type, handler);
        fn(event);
    }
    el.addEventListener(type, handler);
}

// use it like
one(window, 'resize', function () {
    alert("This triggers just once");
});

示例:http://jsfiddle.net/6njpem7x/

【讨论】:

    【解决方案4】:

    addEventListenerremoveEventListener 的组合:

    element.addEventListener("click", clickFunction);
    function clickFunction(e) {
        console.log("clicked");
        element.removeEventListener("click", clickFunction);
    }
    

    jsFiddle

    【讨论】:

    • 也许我没有解释我希望完全实现的目标。我想使用点击事件调用一个函数。然后在此我希望有两个只工作一次的点击功能。对于那个函数调用。为了把它放在上下文中,我正在编写一个函数来绘制一个 SVG 矩形。两次单击用于获取矩形角的画布上的点,整体功能是绘制矩形。
    【解决方案5】:

    类似的东西

    var el = document.getElementById('something');
    el.addEventListener('click', doSomething);
    
    function doSomething() {
      el.removeEventListener('click', doSomething);
    
      //code
    }
    

    【讨论】:

      【解决方案6】:

      其他答案是正确的,因为这可以通过命名函数来实现,但您不需要单独声明该函数。您可以使用命名函数表达式

      element.addEventListener("click", function handler(event) {
        this.removeEventListener("click", handler);
        // ...
      });
      

      另一种方法虽然不太理想,但保留一个变量来跟踪处理程序是否已执行:

      var wasExecuted = false;
      element.addEventListener("click", function(event) {
        if (wasExecuted) {
          return;
        }
        wasExecuted = true;
        // ...
      });
      

      该变量需要在处理程序之外但在范围内声明,以便其值在事件触发器之间保持不变。

      【讨论】:

        【解决方案7】:

        您可以使用通用的内部事件处理程序:e.target.removeEventListener(e.type, arguments.callee)
        或者您可以制作特殊功能来创建“一次性”事件侦听器:

        function oneTimeListener(node, type, callback) {
            // create event
            node.addEventListener(type, function(e) {
                // remove event listener
                e.target.removeEventListener(e.type, arguments.callee);
                // call handler with original context 
                // as it happens with native addEventListener
                return callback.call(this, e); 
            });
        }
        
        oneTimeListener(document.getElementById("myElement"), "click", myHandler);
        

        【讨论】:

          【解决方案8】:

          您可以在第一次点击后设置cookie:

          document.cookie="click=1; expires=.......";
          

          并向侦听器添加条件 - 如果设置了 cookie,则忽略它。

          【讨论】:

          • 我不相信这实际上是 OP 想要的。他说他使用的是 click 事件监听器,而不是 cookie。
          • 从字面上理解一键式 very,我喜欢它!
          • @n-dru 绝对!我的意思是您说 OP 不希望用户能够在后续访问中单击该元素可能是对的。
          • 但它实际上是一个完全有效的答案,有点过度设计但有效,对吧?
          【解决方案9】:

          我正在使用的另一个简单解决方案是向我们正在侦听的元素添加一个虚拟类,这样它就不会再次触发。

          const myButton = document.querySelector('#my-button:not(.init)');
          myButton.addEventListener('click', (e) => {
               e.preventDefault();
               myButton.classList.add('init');
            });
          

          【讨论】:

            猜你喜欢
            • 2010-12-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-11-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多