I can't seem to find an answer to how to accomplish this, yet it's a feature I've seen several times. Essentially I'm echoing out a list and I would like to create the ability to highlight and select these items using arrow keys/enter. Can someone help give me an idea as to how I can accomplish this? I know how to use keycodes (of course), just not how to turn that into functioning code for selecting items on a list...
我似乎无法找到如何实现这一目标的答案,但这是我多次见过的一个功能。基本上我正在回显列表,我想创建使用箭头键/输入突出显示和选择这些项目的功能。有人可以帮助我了解如何实现这一目标吗?我知道如何使用密钥代码(当然),而不是如何将其转换为功能代码以选择列表中的项目...
I was thinking maybe I'd have to have some sort of hidden radio button to mark it as selected or not... but even then I don't know how I would jump from one radio button to the other up and down the list. So if anyone could give me a hand with this I'd really appreciate it. Thank you.
我想也许我必须有一些隐藏的单选按钮来将其标记为选中或不...但即便如此我也不知道如何从一个单选按钮跳到另一个上下列表。所以如果有人能帮我一把,我真的很感激。谢谢。
3 个解决方案
#1
43
Since you didn't really explain what you're having trouble with, I just created a general solution. Hopefully this helps:
既然你没有真正解释你遇到的问题,我就创建了一个通用的解决方案。希望这会有所帮助:
var li = $('li');
var liSelected;
$(window).keydown(function(e) {
if(e.which === 40) {
if(liSelected) {
liSelected.removeClass('selected');
next = liSelected.next();
if(next.length > 0) {
liSelected = next.addClass('selected');
} else {
liSelected = li.eq(0).addClass('selected');
}
} else {
liSelected = li.eq(0).addClass('selected');
}
} else if(e.which === 38) {
if(liSelected) {
liSelected.removeClass('selected');
next = liSelected.prev();
if(next.length > 0) {
liSelected = next.addClass('selected');
} else {
liSelected = li.last().addClass('selected');
}
} else {
liSelected = li.last().addClass('selected');
}
}
});
JSFiddle: http://jsfiddle.net/Vtn5Y/
#2
3
My example for native JavaScript
我的本机JavaScript示例
var ul = document.getElementById('list');
var liSelected;
var index = -1;
document.addEventListener('keydown', function(event) {
var len = ul.getElementsByTagName('li').length-1;
if(event.which === 40) {
index++;
//down
if (liSelected) {
removeClass(liSelected, 'selected');
next = ul.getElementsByTagName('li')[index];
if(typeof next !== undefined && index <= len) {
liSelected = next;
} else {
index = 0;
liSelected = ul.getElementsByTagName('li')[0];
}
addClass(liSelected, 'selected');
console.log(index);
}
else {
index = 0;
liSelected = ul.getElementsByTagName('li')[0];
addClass(liSelected, 'selected');
}
}
else if (event.which === 38) {
//up
if (liSelected) {
removeClass(liSelected, 'selected');
index--;
console.log(index);
next = ul.getElementsByTagName('li')[index];
if(typeof next !== undefined && index >= 0) {
liSelected = next;
} else {
index = len;
liSelected = ul.getElementsByTagName('li')[len];
}
addClass(liSelected, 'selected');
}
else {
index = 0;
liSelected = ul.getElementsByTagName('li')[len];
addClass(liSelected, 'selected');
}
}
}, false);
function removeClass(el, className) {
if(el.classList) {
el.classList.remove(className);
} else {
el.className = el.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' ');
}
};
function addClass(el, className) {
if(el.classList) {
el.classList.add(className);
} else {
el.className += ' ' + className;
}
};
li.selected {background:yellow}
<ul id="list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
#3
0
This may depend on the browser. It seems to work only if the radio inputs are next to each other (label is also ok).
这可能取决于浏览器。它似乎仅在无线电输入彼此相邻时才起作用(标签也可以)。
<input type="radio" ... />
<input type="radio" ... />
<input type="radio" ... />
But this will break radio navigation in Firefox and probably other browsers:
但这会破坏Firefox和其他浏览器中的无线电导航:
<div><input type="radio" ... /> ... </div>
<div><input type="radio" ... /> ... </div>
This is annoying as soon as you want to make something a bit more complex than a simple list (categories...).
一旦你想要制作比简单列表(类别......)更复杂的东西,这就很烦人了。
#1
43
Since you didn't really explain what you're having trouble with, I just created a general solution. Hopefully this helps:
既然你没有真正解释你遇到的问题,我就创建了一个通用的解决方案。希望这会有所帮助:
var li = $('li');
var liSelected;
$(window).keydown(function(e) {
if(e.which === 40) {
if(liSelected) {
liSelected.removeClass('selected');
next = liSelected.next();
if(next.length > 0) {
liSelected = next.addClass('selected');
} else {
liSelected = li.eq(0).addClass('selected');
}
} else {
liSelected = li.eq(0).addClass('selected');
}
} else if(e.which === 38) {
if(liSelected) {
liSelected.removeClass('selected');
next = liSelected.prev();
if(next.length > 0) {
liSelected = next.addClass('selected');
} else {
liSelected = li.last().addClass('selected');
}
} else {
liSelected = li.last().addClass('selected');
}
}
});
JSFiddle: http://jsfiddle.net/Vtn5Y/
#2
3
My example for native JavaScript
我的本机JavaScript示例
var ul = document.getElementById('list');
var liSelected;
var index = -1;
document.addEventListener('keydown', function(event) {
var len = ul.getElementsByTagName('li').length-1;
if(event.which === 40) {
index++;
//down
if (liSelected) {
removeClass(liSelected, 'selected');
next = ul.getElementsByTagName('li')[index];
if(typeof next !== undefined && index <= len) {
liSelected = next;
} else {
index = 0;
liSelected = ul.getElementsByTagName('li')[0];
}
addClass(liSelected, 'selected');
console.log(index);
}
else {
index = 0;
liSelected = ul.getElementsByTagName('li')[0];
addClass(liSelected, 'selected');
}
}
else if (event.which === 38) {
//up
if (liSelected) {
removeClass(liSelected, 'selected');
index--;
console.log(index);
next = ul.getElementsByTagName('li')[index];
if(typeof next !== undefined && index >= 0) {
liSelected = next;
} else {
index = len;
liSelected = ul.getElementsByTagName('li')[len];
}
addClass(liSelected, 'selected');
}
else {
index = 0;
liSelected = ul.getElementsByTagName('li')[len];
addClass(liSelected, 'selected');
}
}
}, false);
function removeClass(el, className) {
if(el.classList) {
el.classList.remove(className);
} else {
el.className = el.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' ');
}
};
function addClass(el, className) {
if(el.classList) {
el.classList.add(className);
} else {
el.className += ' ' + className;
}
};
li.selected {background:yellow}
<ul id="list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
#3
0
This may depend on the browser. It seems to work only if the radio inputs are next to each other (label is also ok).
这可能取决于浏览器。它似乎仅在无线电输入彼此相邻时才起作用(标签也可以)。
<input type="radio" ... />
<input type="radio" ... />
<input type="radio" ... />
But this will break radio navigation in Firefox and probably other browsers:
但这会破坏Firefox和其他浏览器中的无线电导航:
<div><input type="radio" ... /> ... </div>
<div><input type="radio" ... /> ... </div>
This is annoying as soon as you want to make something a bit more complex than a simple list (categories...).
一旦你想要制作比简单列表(类别......)更复杂的东西,这就很烦人了。