1

注意:问题原因已经找到,请阅读第一个答案的评论。

我有一个下拉列表,在用户调用它之前它是隐藏的。是这样的:

<div>
    <button></button>
    <ul>
        <li></li>
        ....
        <li></li>
    </ul>
</div>

基本思想:

当用户按下上面代码中显示的按钮时,列表变得可见。

我需要使列表能够通过键盘导航,
即如果用户在列表打开时向上或向下按下,将选择适当的 li (就好像鼠标悬停在它上面一样)

负责为列表提供此功能的事件侦听器应在列表变为可见时附加,并在列表再次隐藏时删除。

类似于 Bitbucket 为下拉列表所做的事情,但更简单。

问题:

我尝试将事件侦听器附加到 ul ,然后附加到 div 元素上,当前者无效时,无济于事。
代码是这样的

展出

this.<ul or div element here>.addEventListener('keydown', this.keyboardNavigation.bind(this));

隐藏

this.<ul or div element here>.removeEventListener('keydown', this.keyboardNavigation.bind(this));

回调是这样的

function keyboardNavigation(e) {
    console.log('foo');
}

注意: “this”是一个对象,它的 div 和 ul 都是其属性,回调函数实际上是该对象的一个​​方法。

问题 1:
为什么keydown当我将它附加到 ul 本身或父 div 时,事件不起作用?

无论如何,由于这些不起作用,我决定将侦听器附加到文档中。
展出

document.addEventListener('keydown', this.keyboardNavigation.bind(this));

隐藏

document.removeEventListener('keydown', this.keyboardNavigation.bind(this));

相同的回调。

现在,虽然这可行,但我注意到事件侦听器并未从文档中删除。
后来我注意到,keydown我为另一个任务附加到文档的另一个事件侦听器在该任务完成时也没有被删除,而它应该被删除。

问题 2:
为什么没有删除事件侦听器?我无法理解我做错了什么,我正在删除与添加的完全相同的事件的完全相同的回调。

任何帮助都感激不尽。

注意: 我尝试过使用 jQuery.on().off()代替,正如这里所建议的那样,虽然我不想使用 jQuery,但同样的事情正在发生。

4

1 回答 1

2

我的想法:

1 是因为 DIV 或 UL 没有获得键盘事件,因为没有焦点?而文档总是得到冒泡事件?

要对此进行测试,请单击 DIV/UL 并键入,然后查看是否触发了键盘事件。

我认为绑定到文档 - 如果您希望用户能够在单击后开始输入 - 是正确的做法。

2 这是因为您没有删除您创建的同一个处理程序吗?您应该保留对使用第一个绑定调用创建的处理程序的引用,并将此引用传递给 remove 调用 - 否则您将创建另一个(不同的)处理程序并要求删除它。

例如:

var f = this.keyboardNavigation.bind(this);
document.addEventListener('keydown', f);
document.removeEventListener('keydown', f);
于 2013-06-21T03:57:43.873 回答