javascript - 为什么函数执行后事件监听器不立即被删除?

标签 javascript html css

我期望的是,当我点击按钮 4 时,事件监听器应该立即按钮 1 中删除,但实际上是什么发生的情况是,事件监听器仅在单击按钮 1 一次后停止。

var btn = document.querySelector('.container').children;

for (let x = 0; x < btn.length; x++) {

  btn[x].addEventListener('click', changeFontSize);

  function changeFontSize() {
    // changing the font sizes from 16 to 20 , or the opposite.
    if (getComputedStyle(btn[x]).fontSize == '16px') {
      btn[x].style.fontSize = '20px';
    } else {
      btn[x].style.fontSize = '16px';
    }

    // nesting a function to remove the event listener form btn0 after btn4 gets clicked on
    if (getComputedStyle(btn[3]).fontSize == '20px') {
      btn[0].removeEventListener('click', changeFontSize);
    }
  }
}
button {
  font-size: 1em;
}
<div class="container">
  <button id='btn'>btn 1</button>
  <button id='btn'>btn 2</button>
  <button id='btn'>btn 3</button>
  <button id='btn'>btn 4</button>
  <button id='btn'>btn 1</button>
</div>

最佳答案

当执行按钮 4 的事件监听器删除时,它会尝试在按钮 1 的闭包中删除其对 function changeFontSize() 的引用。此操作失败,因为按钮 1 没有按钮 4 的引用处理程序附加到它。点击按钮4后,可能会处于其fontSize == "20px"为true的状态。下次您在按钮 4 处于这种状态下单击按钮 1 时,按钮 1 会成功删除其自己的监听器,但前提是最后一次更改其字体大小。

此外,当按钮 4 处于 fontSize == "20px" 状态时,单击时,所有其他按钮中的 if 都会徒劳地尝试从按钮 0 中删除其监听器.

问题的最小重现:

const [foo, bar] = document.querySelectorAll("button");
let barClicked = false;

function fooClickHandler () {
  console.log("foo clicked");
  
  if (barClicked) {
    foo.removeEventListener("click", fooClickHandler);
    console.log("foo listener removed");
  }
}

function barClickHandler () {
  console.log("bar clicked");
  barClicked = true;
  foo.removeEventListener("click", barClickHandler); // does nothing
}

foo.addEventListener("click", fooClickHandler);
bar.addEventListener("click", barClickHandler);
<button>foo</button>
<button>bar</button>

您可以将事件处理程序回调函数存储在专门用于按钮 1 的变量中,并确保按钮 4 的处理程序准确删除按钮 1 的处理程序函数。但整体设计看起来相当脆弱,因此我建议重新考虑,具体取决于您的应用程序上下文。

顺便说一句,我不确定 CSS 中的 1em 是否能保证您的初始 16px 大小。如果您期望的话,我会在 CSS 中将其明确设置为 16px。将这些大小硬编码到 JS 中有点代码味道。

Id 在整个 DOM 中必须是唯一的,但这里不是这样的。

顺便说一句,始终使用 === 而不是 ==const/let 而不是一般来说,var,尽管这不是这里的错误。

关于javascript - 为什么函数执行后事件监听器不立即被删除?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66728712/

相关文章:

javascript - 谷歌应用脚​​本: How do I pull data entered today from one spreadsheet and transpose it to another?

php - 在MySQL多重插入中将数组值连接到字符串中

php - html 和 php 使用相同的 css 文件吗?

Html:调整页面大小时图像将换行

javascript - 单击下拉菜单移动不工作

javascript - 突出显示文本的搜索栏

javascript - 是否可以从 google Plus Badge(添加到圈子)获得回调?

javascript - 普通 JS : make 80% width element 100% IF contains an image

javascript - 键盘事件在 Chrome 53 中不起作用

css - 我的 div 没有留在我的 div 容器内