在 JavaScript 中使用箭头键移动焦点
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11088674/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Shift focus with arrow keys in JavaScript
提问by Kay Lamerigts
I want to be able to navigate through all the focusable elements on my webpage with the arrow key. So when the down-key is pressed the focus should shift to the focusable element beneath the current focussed element. You get the idea for the other arrow keys, when there is not a focusable element to shift to, the focus should remain the same.
我希望能够使用箭头键浏览网页上所有可聚焦的元素。因此,当按下向下键时,焦点应移至当前聚焦元素下方的可聚焦元素。您了解其他箭头键的想法,当没有可聚焦的元素转移到时,焦点应保持不变。
This is what I got so far:
这是我到目前为止得到的:
$(document).keydown(function(e){
if (e.keyCode == 37) { //left
var offset = $("*:focus").offset();
var allElements = $("#container").find('a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, *[tabindex], *[contenteditable]');
var arr = jQuery.makeArray(allElements);
var topLeft = offset.left
var minus = topLeft;
var currentElement = $("*:focus");
for(var i = 0; i < arr.length; i++)
{
if ( (arr[i].offset().left < offset.left) // This doesn't work for some reason
&& ((offset.left - arr[i].offset().left) < minus))
{
currentElement = arr[i];
minus = offset.left - arr[i].offset().left;
topLeft = arr[i].offset().left;
}
currentElement.focus();
}
alert( "left pressed" );
return false;
}
// Other Keys
});
});
the idea was to get all the focus-able elements and than pick select the one that is suited for the arrow and shift focus.
我们的想法是获得所有可聚焦的元素,然后选择适合箭头和移动焦点的元素。
I'm not able to get this code to work (it contains a error) and I'm not completly sure it will even work.
我无法让这段代码工作(它包含一个错误),我不确定它甚至会工作。
Thnx in advance
提前谢谢
[EDIT]: I guess I was a little vague. I do not only want to go left and right, but also up and down.
[编辑]:我想我有点含糊。我不仅要左右走,还要上下。
回答by Cranio
What I would do is much simpler. Just add a common class among the objects who should have this functionality (f.ex. "move") and use:
我要做的事情要简单得多。只需在应该具有此功能的对象中添加一个公共类(例如“移动”)并使用:
$(document).keydown(
function(e)
{
if (e.keyCode == 39) {
$(".move:focus").next().focus();
}
if (e.keyCode == 37) {
$(".move:focus").prev().focus();
}
}
);
?
See example: http://jsfiddle.net/uJ4PJ/
参见示例:http: //jsfiddle.net/uJ4PJ/
This code is muchsimpler and hopefully has all the functionality you need.
这段代码要简单得多,希望拥有您需要的所有功能。
Just make sure the controls are in the correct orderor this won't work properly.
只需确保控件的顺序正确,否则将无法正常工作。
回答by user2462210
After much trial and error, I developed this code that works :
经过多次反复试验,我开发了这个有效的代码:
function navigate(origin, sens) {
var inputs = $('#form').find('input:enabled');
var index = inputs.index(origin);
index += sens;
if (index < 0) {
index = inputs.length - 1;
}
if (index > inputs.length - 1) {
index = 0;
}
inputs.eq(index).focus();
}
$('input').keydown(function(e) {
if (e.keyCode==37) {
navigate(e.target, -1);
}
if (e.keyCode==39) {
navigate(e.target, 1);
}
});
right arrow acts as tab
右箭头充当标签
left arrow acts as shift tab
左箭头充当移位选项卡
回答by Jānis
Preview - http://jsfiddle.net/FehKh/;)
预览 - http://jsfiddle.net/FehKh/;)
html:
html:
<a href='jqwja' class="focusable">jajaj</a>
<a href='jjaasd' class="focusable focused">jajasdaaj</a>
<a href='jjqwea' class="focusable">jajaacasj</a>
<input value='iddqd' name="DoomII" class="focusable" />?
js:
js:
// init
$('.focused').focus();
// actual code
$(document).keydown(function(e){
if (e.keyCode == 37) { // left
if($('.focused').prev('.focusable').length)
$('.focused').removeClass('focused').prev('.focusable').focus().addClass('focused');
}
if (e.keyCode == 39) { // right
if($('.focused').next('.focusable').length)
$('.focused').removeClass('focused').next('.focusable').focus().addClass('focused');
}
});?
回答by Ahmad Shakil
Implemented above by checking some articles and stack over flow links
上面通过检查一些文章和stack over flow链接来实现
jQuery.fn.elementAfter = function(other) {
for(i = 0; i < this.length - 1; i++) {
if (this[i] == other) {
return jQuery(this[i + 1]);
}
}
return jQuery;
} ;
jQuery.fn.elementBefore = function(other) {
if (this.length > 0) {
for(i = 1; i < this.length; i++) {
if (this[i] == other) {
return jQuery(this[i - 1]);
}
}
}
return jQuery;
};
回答by Axel EsZu
This works great
这很好用
$('p').each(function(index) {
$(this).attr('tabindex', index)
}).on('keyup', function(e) {
e.preventDefault;
if (e.keyCode == 39) {
$('[TabIndex="' + Number(Number($(this).attr('tabindex')) + 1) + '"]').focus();
}
if (e.keyCode == 37) {
$('[TabIndex="' + Number(Number($(this).attr('tabindex')) - 1) + '"]').focus();
}
});
回答by baron_bartek
None of above solutions worked for me. This one is mine. It look difficult but it's accually real easy. Create array
of link and change focus using the array index
. (I needed up/down arrow so keycodes are different). It also works with dynamicly
added links (cause I needed it this way, that is why I use on
)
以上解决方案都不适合我。这个是我的。看起来很难,但实际上很容易。array
使用数组创建链接并更改焦点index
。(我需要向上/向下箭头,所以键码不同)。它也适用于dynamicly
添加的链接(因为我需要这种方式,这就是我使用的原因on
)
$('#links_container').on("keydown", ".link",
function(e)
{
//start - list of <a>
var flag = false;
var smallMeni = document.getElementById('links_container');
var allElements2 = smallMeni.getElementsByTagName('a'); //.link
//end
//start - key down
if (e.keyCode == 40)
{
for (var i=0;i<allElements2.length;i++)
{
if(flag == true){
flag = false
allElements2[i].focus();
//alert(i)
}
else
{
if ( document.activeElement === allElements2[i] )
{
//alert(i);
flag = true;
}
}
}
}
//end
//start - key up
if (e.keyCode == 38)
{
for (var i=0;i<allElements2.length;i++)
{
if ( document.activeElement === allElements2[i] )
{
if (i>0)
{
allElements2[i-1].focus();
}
}
}
}
//alert(i);
}
);
回答by nithin guptha
this library has similar implementation: keyboard-navigator.
shifts focus by getting next directional node by comparing coordinates.
but you will have to supply this function with all the nodes that you want to navigate upon(fromNodes).
这个库有类似的实现:keyboard-navigator。
通过比较坐标获取下一个方向节点来转移焦点。
但是您必须为要导航的所有节点(fromNodes)提供此功能。
getNextDirectionalNode = function (activeNode,fromNodes,direction,coordinatesDeviationFactor=0){
var filteredNodes = []
var indexOfReturningElem = 0;
if(direction == "down"){
for(var i=0; i<fromNodes.length; i++)
{
if( this.inDeviationRange(fromNodes[i].getBoundingClientRect().x,activeNode.getBoundingClientRect().x,coordinatesDeviationFactor) &&
(fromNodes[i].getBoundingClientRect().y > activeNode.getBoundingClientRect().y)
)
{
filteredNodes.push(fromNodes[i])
}
}
indexOfReturningElem = 0;
if( indexOfReturningElem >= 0 && (indexOfReturningElem <= filteredNodes.length-1) ){
return filteredNodes[indexOfReturningElem];
}
}
if(direction == "up"){
for(var i=0; i<fromNodes.length; i++)
{
if( this.inDeviationRange(fromNodes[i].getBoundingClientRect().x,activeNode.getBoundingClientRect().x,coordinatesDeviationFactor) &&
(fromNodes[i].getBoundingClientRect().y < activeNode.getBoundingClientRect().y)
)
{
filteredNodes.push(fromNodes[i])
}
}
indexOfReturningElem = filteredNodes.length - 1;
if( indexOfReturningElem >= 0 && (indexOfReturningElem <= filteredNodes.length-1) ){
return filteredNodes[indexOfReturningElem];
}
}
if(direction == "right"){
for(var i=0; i<fromNodes.length; i++)
{
if( this.inDeviationRange(fromNodes[i].getBoundingClientRect().y,activeNode.getBoundingClientRect().y,coordinatesDeviationFactor) &&
(fromNodes[i].getBoundingClientRect().x > activeNode.getBoundingClientRect().x)
)
{
filteredNodes.push(fromNodes[i])
}
}
indexOfReturningElem = 0;
if( indexOfReturningElem >= 0 && (indexOfReturningElem <= filteredNodes.length-1) ){
return filteredNodes[indexOfReturningElem];
}
}
if(direction == "left"){
for(var i=0; i<fromNodes.length; i++)
{
if( this.inDeviationRange(fromNodes[i].getBoundingClientRect().y,activeNode.getBoundingClientRect().y,coordinatesDeviationFactor) &&
(fromNodes[i].getBoundingClientRect().x < activeNode.getBoundingClientRect().x)
)
{
filteredNodes.push(fromNodes[i])
}
}
indexOfReturningElem = filteredNodes.length - 1;
if( indexOfReturningElem >= 0 && (indexOfReturningElem <= filteredNodes.length-1) ){
return filteredNodes[indexOfReturningElem];
}
}
return null;
}