Javascript JS ArrowDown为循环中的多个元素添加了EventListener(演示)
为键盘Javascript JS ArrowDown为循环中的多个元素添加了EventListener(演示),javascript,events,loops,listener,arrow-keys,Javascript,Events,Loops,Listener,Arrow Keys,为键盘ArrowDown事件设置以下侦听器(其键代码为40): window.onload=function(){ var itemsContainer=document.getElementById('cities-drop'); document.addEventListener('keyup',函数(事件){ if(event.keyCode==40&&itemsContainer.style.display==block){ event.preventDefault(); 对于(var
ArrowDown
事件设置以下侦听器(其键代码为40
):
window.onload=function(){
var itemsContainer=document.getElementById('cities-drop');
document.addEventListener('keyup',函数(事件){
if(event.keyCode==40&&itemsContainer.style.display==block){
event.preventDefault();
对于(var i=0;i在查看代码并了解您试图执行的操作后,我认为您的错误是使用了substr
,您应该使用indexOf
。以下是更新的行:
if (itemsContainer.getAttribute('class').indexOf('hovered') != -1)
更多详细信息:
实际上,您使用的是一个substr
和一个字符串值作为start
索引。不确定结果会是什么,但显然不是-1,因为条件每次都返回true,导致下一个元素每次悬停,一直到列表底部。使用break
语句,它在第一个元素执行if语句(导致第二个元素被“悬停”),然后退出
更正代码后,我会将break
语句留在那里,以便循环在找到匹配项后停止,而不会不必要地循环其他项
编辑:
我在您的代码中还发现了一些其他问题。下面是一个在IE和FF中适用的示例,至少(没有在Safari、Opera或Chrome中测试过):
.盘旋
{
颜色:红色;
}
功能移动(事件)
{
var itemsContainer=document.getElementById('cities-drop');
if(event.keyCode==40&&itemsContainer.style.display==block)
{
if(event.preventDefault)
event.preventDefault();
if(event.cancelBubble)
event.cancelBubble();
if(事件停止立即复制)
事件。stopImmediatePropagation();
对于(var i=0;i,我可以看到一些事情可能是个问题
itemsContainer.children[i].nextSibling
即itemsContainer.children[i+1]
。这就是为什么如果跳过中断,它总是选择最后一个元素。如果有与类匹配的项,itemsContainer[i+1]将始终悬停
第二个问题是Travesty3在他的回答中指出了什么
我还更改了if条件,以检查悬停的类是否在其中一个子类上,而不是容器本身
if (itemsContainer.children[i].getAttribute('class').match('hovered'))
我用以下代码行修改了事件处理程序,这似乎很好:
document.addEventListener('keyup',function(event){
if (event.keyCode === 40 && itemsContainer.style.display==='block') {
event.preventDefault();
for (var i=0,l=itemsContainer.children.length;i<l;++i){
if (itemsContainer.children[i].getAttribute('class').match('hovered')){
itemsContainer.children[i].setAttribute('class','');
itemsContainer.children[i+1].setAttribute('class','hovered');
break;
}
}
}
});
document.addEventListener('keyup',函数(事件){
if(event.keyCode==40&&itemsContainer.style.display==block){
event.preventDefault();
对于(var i=0,l=itemsContainer.children.length;i您可以尝试一种更简单的方法,而不是使用循环:
window.onload = function() {
var itemsContainer = document.getElementById('cities-drop');
document.addEventListener('keyup',function(event) {
if (event.keyCode == 40 && itemsContainer.style.display=='block') {
event.preventDefault();
var previousHoveredChoice = itemsContainer.querySelector('.hovered');
previousHoveredChoice.className = '';
var currentHoveredChoice = previousHoveredChoice.nextSibling;
if (currentHoveredChoice) {
currentHoveredChoice.className = 'hovered';
}
}
});
//following code is copy-pasted from the live example
//just to close the onload function handler in this solution
document.addEventListener('keyup',function(event){
if (event.keyCode == 27) {
if (document.getElementById('cities-drop').style.display=='block'){
document.getElementById('cities-drop').style.display='none';
}
}
});
//end of copy-pasted code
};
你想实现什么?自定义下拉菜单?@Šime Vidas你完全正确为什么你想自己编写它?有一些库和框架提供这种功能。@Šime Vidas我知道。这是我JS学习计划中的任务。我说的更多-我用纯JS编写它。你想实现什么?你想选择吗列表中的一个项目有向上箭头键和向下箭头键?是的,这是我的错误,我错误地使用了substr
。无论如何,这对我没有帮助,无论是indexOf()
,还是match())
,很抱歉反应太晚。你在这里写的那个版本对我很有效。从另一个角度看,我不需要内联观察者onkeydown=move(event)
,所以当我尝试使用addEventListener
时,我会给你fedback@sergionni:请记住,addEventListener
在IE中不受支持,IE仍然是最常用的浏览器之一。您将在Internet Explorer中遇到一个Javascript错误,即对象不支持此属性或方法。
。如果您如果不使用此方法,则应首先执行检查以查看函数是否存在。请参见示例。是的,我知道attachEvent
和addEventListener
。这不是问题。主要问题是我需要侦听器,而不是“内联观察者”。@sergionni:我不明白你所说的“内联观察者”是什么意思…使用内联方法附加事件仍将以与使用addEventListener
相同的方式执行该功能。我所知道的唯一区别是,如果尝试使用内联方法向同一事件添加另一个操作,则会覆盖上一个操作,而使用addEventListener
,这两个操作都会被覆盖s将执行。因此,内联方法仍然是一个事件侦听器,完全相同。似乎您忘记更新if语句:if(itemsContainer.children[i].getAttribute('class').match('hovered')){
document.addEventListener('keyup',function(event){
if (event.keyCode === 40 && itemsContainer.style.display==='block') {
event.preventDefault();
for (var i=0,l=itemsContainer.children.length;i<l;++i){
if (itemsContainer.children[i].getAttribute('class').match('hovered')){
itemsContainer.children[i].setAttribute('class','');
itemsContainer.children[i+1].setAttribute('class','hovered');
break;
}
}
}
});
window.onload = function() {
var itemsContainer = document.getElementById('cities-drop');
document.addEventListener('keyup',function(event) {
if (event.keyCode == 40 && itemsContainer.style.display=='block') {
event.preventDefault();
var previousHoveredChoice = itemsContainer.querySelector('.hovered');
previousHoveredChoice.className = '';
var currentHoveredChoice = previousHoveredChoice.nextSibling;
if (currentHoveredChoice) {
currentHoveredChoice.className = 'hovered';
}
}
});
//following code is copy-pasted from the live example
//just to close the onload function handler in this solution
document.addEventListener('keyup',function(event){
if (event.keyCode == 27) {
if (document.getElementById('cities-drop').style.display=='block'){
document.getElementById('cities-drop').style.display='none';
}
}
});
//end of copy-pasted code
};