防止多个事件同时调用函数

时间:2017-06-20 20:27:31

标签: javascript jquery javascript-events

element.on('click focus', function (e) {
    // Do Something
}

在我的例子中,做一些事情会跑两次。我希望每次互动只运行一次。

我正在使用焦点,因此用户可以选中要触发事件的元素,或者点击它来触发事件。

如果用户多次与其进行交互(标签打开,然后关闭,再重新打开),则可以多次触发该事件。

4 个答案:

答案 0 :(得分:1)

我的想法是这种行为有问题,但是根据您的描述,这是处理您为菜单详细说明的事件的一般想法。这里的工作演示:https://jsfiddle.net/mcso7q1y/

HTML:

<button id="btn">Click Me</button>

<ul id="menu">
     <li>This is a menu.</li>
     <li>This is a menu.</li>
     <li>This is a menu.</li>
     <li>This is a menu.</li>
</ul>

jQuery的:

$(document).ready(function(){
    $("#menu").slideUp("fast");
    var closed = true;

    $("#btn").click(function(){                       
          menuToggle(closed);
          closed = !closed;
    });

    $("#btn").focus(function(){
         menuToggle(closed);
         closed = !closed;
    });

    $("#btn").focusout(function(){
         menuToggle(closed);
         closed = !closed;
    });
});

function menuToggle(clsd){
    if(clsd){ 
        $("#menu").slideDown();          
    } else {
        $("#menu").slideUp();          
    }
}

答案 1 :(得分:0)

创建一个名为done的变量,如果falsedone并且更改false,则仅在触发该功能时将其设置为done在函数结束时到true,所以如果再次触发函数,那么“Do Something”将不会执行,因为'done'设置为true

var done = false;

element.on('click focus', function (e) {
    if( !done ) {
        // Do Something
    }

    done = !done;
}

答案 2 :(得分:0)

你可以滚动你自己的处理多个事件的方法,使用轻微的超时来限制事件,这样只会触发一个事件等。

$.fn.onMulti = function() {
  var temp = [].slice.call(arguments), fn = temp.pop();

  return this.on(...temp, function() {
    clearTimeout($(this).data('multiTimer'));
    $(this).data('multiTimer', setTimeout(fn.bind(this, arguments), 200))
  });
}

&#13;
&#13;
$.fn.onMulti = function() {
  var temp = [].slice.call(arguments), fn = temp.pop();

  return this.on(...temp, function() {
    clearTimeout($(this).data('multiTimer'));
    $(this).data('multiTimer', setTimeout(fn.bind(this, arguments), 200))
  });
}

/* To be used like */

var element = $('a'), i = 0;

element.onMulti('click focus', function(e) {
  console.log('works : ' + (++i));
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="#">Active Element Anchor, fires events on click and focus</a>
<br />
<br />
<br />
<div>Element to click on to remove focus</div>
&#13;
&#13;
&#13;

答案 3 :(得分:-1)

我会在这里提出一个不同的方法。而不是处理全局变量和所有这些,跟踪菜单的状态,并在必要时切换。

&#13;
&#13;
second
&#13;
$(function() {
  function Menu(element) {
    this.isOpen = false;
    this.element = element;
    $(this.element).on('focusin', this.open.bind(this));
    $(this.element).on('focusout', this.close.bind(this));
    $(this.element).on('click', this.open.bind(this));
  }
  Menu.prototype.open = function() {
    this.isOpen = true;
    this.update();
  }
  Menu.prototype.close = function() {
    this.isOpen = false;
    this.update();
  }
  Menu.prototype.update = function() {
    $(this.element).toggleClass('open', this.isOpen);
  }

  $('.item').each(function (ix, el) { new Menu(el); });

});
&#13;
.item .submenu {
  display: none;
}

.item.open .submenu {
  display: block;
}
&#13;
&#13;
&#13;

您可能需要考虑编写一个jQuery插件而不是所有这些插件(或者使用现有的插件中的一个)。