防止在第一个事件后捕获事件

Prevent event capturing after first event

我有一个代码:https://jsfiddle.net/AleshaOleg/zj69u8Lz

document.querySelector('.js-delete').addEventListener('click', function(e) {
  event(e, trigger);
});

function event(e, callback) {
  e.target.addEventListener('transitionend', function(e) {
    e.target.removeEventListener(e.type, arguments.callee);
    callback(e);
  });
}

function trigger(e) {
  alert("DONE");
}
.js-delete {
  -webkit-transition: width .3s;
  transition: width .3s;
  width: 100px;
}

.js-delete:hover {
  width: 100%;
}
<button class="js-delete">Delete</button>

其中,我在点击时有事件监听器,点击后内部又发生了一个事件,该事件在转换结束后触发,并且应该可以看到警告消息。

一切正常。但问题是,当我点击超过 1 次时,在转换结束之前,我将收到相同数量的警报消息。

所以,我想单独获得一个警报,我点击了我的按钮多少次。

谢谢!

这对我来说似乎是一个黑客,但我添加了一个我切换的变量 busy,所以如果它已经被调用,它就不会被调用

var busy=false;

document.querySelector('.js-delete').addEventListener('click', function(e) {
 if(!busy){
  busy=true;
  event(e, trigger);
  }
});

function event(e, callback) {
  e.target.addEventListener('transitionend', function(e) {
    e.target.removeEventListener(e.type, arguments.callee);
    callback(e);
  });
}

function trigger(e) {
  alert("DONE");
  busy=false;
}
.js-delete {
  -webkit-transition: width .3s;
  transition: width .3s;
  width: 100px;
}

.js-delete:hover {
  width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="js-delete">Delete</button>

之所以会发生这种情况,是因为每次单击该按钮时,您都会向 'transitionend' 注册一个新的 eventListener ... 老实说,我不确定您为什么要这样做。将您的代码修改为:

function event(e, callback) {
    e.target.removeEventListener(e.type, arguments.callee);
    callback(e);
}

每次单击删除按钮时,您都会向 transitionend 添加多个事件侦听器。我已经调整了您的代码,看看是否可行:

var clickHandler = function(e) {
    event(e, trigger);
}

document.querySelector('.js-delete').addEventListener('click',clickHandler);

function event(e, callback) {
  e.target.addEventListener('transitionend', function(e) {
      e.target.removeEventListener(e.type, arguments.callee);
      callback(e);
   });
}

function trigger(e) {
   alert("DONE");
   e.target.removeEventListener(e.type, clickHandler);
}

我不会使用 arguments.callee,它已被弃用(不适用于 'strict mode')。

只需为事件处理程序使用命名函数而不是匿名函数,这样删除它们会更容易。

还有一些包装函数可以再次添加事件处理程序。

// Start application lifecycle by registering click event
registerClickHandler();

function registerClickHandler() {
  document.querySelector('.js-delete').addEventListener('click', clickHandler);
}

function clickHandler(e) {
  // Immediatley remove click event handler after event fired
  e.target.removeEventListener(e.type, clickHandler);
  // Register transition event handler
  registerTransitionHandler(e);
}

function registerTransitionHandler(e) {
  e.target.addEventListener('transitionend', transitionHandler);
}

function transitionHandler(e) {
  // Immediately remove transitionend event handler after event fired
  e.target.removeEventListener(e.type, transitionHandler);
  // Register click event again
  registerClickHandler();
  // Run callback at transitionend event
  transitionEndCallback(e);
}

function transitionEndCallback(e) {
  alert("DONE");
}
.js-delete {
  -webkit-transition: width .3s;
  transition: width .3s;
  width: 100px;
}
.js-delete:hover {
  width: 100%;
}
<button class="js-delete">Delete</button>