在标签索引中关注下一个元素

Jad*_*aMD 82 javascript jscript.net

我试图根据具有焦点的当前元素将焦点移动到制表序列中的下一个元素.到目前为止,我的搜索中没有任何内容.

function OnFocusOut()
{
    var currentElement = $get(currentElementId); // ID set by OnFocusIn 

    currentElementId = "";
    currentElement.nextElementByTabIndex.focus();
}
Run Code Online (Sandbox Code Playgroud)

当然nextElementByTabIndex是这个工作的关键部分.如何在标签序列中找到下一个元素?解决方案需要使用JScript而不是JQuery.

Chr*_*alo 62

我从来没有实现过这个,但我已经研究过类似的问题了,这就是我想要的.

先试试这个

首先,我会看看你是否可以简单地在当前具有焦点的元素上触发keypress Tab键事件.对于不同的浏览器,可能有不同的方法.

如果这不起作用,你将不得不更加努力......

引用jQuery实现,您必须:

  1. 听取Tab和Shift + Tab
  2. 知道哪些元素是可以选择的
  3. 了解Tab键顺序的工作原理

1.听取Tab和Shift + Tab

倾听Tab和Shift + Tab可能在网络上的其他地方都有很好的涵盖,所以我会跳过那一部分.

2.了解哪些元素可以选项

知道哪些元素是可制表的是棘手的.基本上,如果元素是可聚焦的并且没有tabindex="-1"设置属性,则该元素是可制表的.那么我们必须要问哪些要素是可集中的.以下元素是可聚焦的:

  • input,select,textarea,button,和object没有被禁用的元素.
  • aarea具有href或具有tabindexset 的数值的元素.
  • 任何具有tabindexset 数值的元素.

此外,只有在以下情况下才能聚焦元素:

  • 它的祖先都不是display: none.
  • 计算出的值visibilityvisible.这意味着要visibility设置的最近祖先必须具有值visible.如果没有visibility设置祖先,则计算出的值为visible.

更多细节在另一个Stack Overflow答案中.

3.了解Tab键顺序的工作原理

文档中元素的Tab键顺序由tabindex属性控制.如果没有设置值,tabindex则有效0.

tabindex文件的顺序是:1,2,3,...,0.

最初,当body元素(或没有元素)具有焦点时,Tab键顺序中的第一个元素是最低的非零值tabindex.如果多个元素具有相同的元素tabindex,则按文档顺序进行,直到到达最后一个元素tabindex.然后你移动到下一个最低点tabindex,然后继续.最后,使用零(或空)的元素完成tabindex.

  • 82 票赞成,没有一条评论表明_哪个_建议的解决方案确实有效? (20认同)

Mx.*_*Mx. 31

这是我为此目的建立的东西:

focusNextElement: function () {
    //add all elements we want to include in our selection
    var focussableElements = 'a:not([disabled]), button:not([disabled]), input[type=text]:not([disabled]), [tabindex]:not([disabled]):not([tabindex="-1"])';
    if (document.activeElement && document.activeElement.form) {
        var focussable = Array.prototype.filter.call(document.activeElement.form.querySelectorAll(focussableElements),
        function (element) {
            //check for visibility while always include the current activeElement 
            return element.offsetWidth > 0 || element.offsetHeight > 0 || element === document.activeElement
        });
        var index = focussable.indexOf(document.activeElement);
        if(index > -1) {
           var nextElement = focussable[index + 1] || focussable[0];
           nextElement.focus();
        }                    
    }
}
Run Code Online (Sandbox Code Playgroud)

特征:

  • 可配置的可聚焦元素集
  • 不需要jQuery
  • 适用于所有现代浏览器
  • 快速轻巧

  • 这是最有效和资源友好的解决方案.谢谢!这是我的完整工作脚本:http://stackoverflow.com/a/40686327/1589669 (2认同)
  • 很好的方法,但它应该允许任何不是“hidden”类型的输入,并且还涵盖“textarea”和“select”。 (2认同)

Mar*_*ijk 23

我创建了一个简单的jQuery插件,它就是这样做的.它使用jQuery UI的':tabbable'选择器来查找下一个'tabbable'元素并选择它.

用法示例:

// Simulate tab key when element is clicked 
$('.myElement').bind('click', function(event){
    $.tabNext();
    return false;
});
Run Code Online (Sandbox Code Playgroud)

  • 对于那些不想安装插件的人来说,有一个简短的预览: `var selectables = $(':focusable');` `var currentIndex = selectables.index($(':focus'));` `selectables. eq(currentIndex + 1).focus();` 该插件具有错误检查和更多选项。 (2认同)

Bri*_*laz 20

没有jquery:首先,在你的可选项元素上,添加class="tabable"它将让我们稍后选择它们.(不要忘记下面代码中的"."类选择器前缀)

var lastTabIndex = 10;
function OnFocusOut()
{
    var currentElement = $get(currentElementId); // ID set by OnFOcusIn
    var curIndex = currentElement.tabIndex; //get current elements tab index
    if(curIndex == lastTabIndex) { //if we are on the last tabindex, go back to the beginning
        curIndex = 0;
    }
    var tabbables = document.querySelectorAll(".tabable"); //get all tabable elements
    for(var i=0; i<tabbables.length; i++) { //loop through each element
        if(tabbables[i].tabIndex == (curIndex+1)) { //check the tabindex to see if it's the element we want
            tabbables[i].focus(); //if it's the one we want, focus it and exit the loop
            break;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 一个解决方案,无需为每个元素添加一个名称(如果可行,有许多方法可以制作)将是理想的. (11认同)
  • 请注意,使用flexbox时,DOM中元素的顺序与浏览器中的可视元素顺序不同.当您使用flexbox更改元素的顺序时,只选择下一个tabbable元素不起作用. (4认同)
  • 好的,这是表格吗?如果你想要的所有元素都是输入元素,你可以替换`var tabbables = document.getElementsByName("tabable");````var tabbables = document.getElementsByTagName("input");` (3认同)
  • class ="tabbable"而不是使用name属性 (2认同)

And*_*ang 7

答案的核心在于找到下一个元素:

  function findNextTabStop(el) {
    var universe = document.querySelectorAll('input, button, select, textarea, a[href]');
    var list = Array.prototype.filter.call(universe, function(item) {return item.tabIndex >= "0"});
    var index = list.indexOf(el);
    return list[index + 1] || list[0];
  }
Run Code Online (Sandbox Code Playgroud)

用法:

var nextEl = findNextTabStop(element);
nextEl.focus();
Run Code Online (Sandbox Code Playgroud)

请注意,我不关心优先级tabIndex.

  • 如果tabindex顺序与文档顺序相反怎么办?我认为该数组必须按tabindex编号然后按文档顺序排序 (2认同)

cho*_*wey 6

似乎您可以检查tabIndex元素的属性来确定它是否可聚焦。不可聚焦的元素的值为tabindex“-1”。

那么你只需要知道制表位的规则:

  • tabIndex="1"具有最高优先级。
  • tabIndex="2"具有下一个最高优先级。
  • tabIndex="3"是下一个,依此类推。
  • tabIndex="0"(或默认情况下可选项)具有最低优先级。
  • tabIndex="-1"(或者默认情况下不可选项)不充当制表位。
  • 对于具有相同 tabIndex 的两个元素,在 DOM 中第一个出现的元素具有更高的优先级。

以下是如何使用纯 Javascript 按顺序构建制表位列表的示例:

function getTabStops(o, a, el) {
    // Check if this element is a tab stop
    if (el.tabIndex > 0) {
        if (o[el.tabIndex]) {
            o[el.tabIndex].push(el);
        } else {
            o[el.tabIndex] = [el];
        }
    } else if (el.tabIndex === 0) {
        // Tab index "0" comes last so we accumulate it seperately
        a.push(el);
    }
    // Check if children are tab stops
    for (var i = 0, l = el.children.length; i < l; i++) {
        getTabStops(o, a, el.children[i]);
    }
}

var o = [],
    a = [],
    stops = [],
    active = document.activeElement;

getTabStops(o, a, document.body);

// Use simple loops for maximum browser support
for (var i = 0, l = o.length; i < l; i++) {
    if (o[i]) {
        for (var j = 0, m = o[i].length; j < m; j++) {
            stops.push(o[i][j]);
        }
    }
}
for (var i = 0, l = a.length; i < l; i++) {
    stops.push(a[i]);
}
Run Code Online (Sandbox Code Playgroud)

我们首先遍历 DOM,按顺序收集所有制表位及其索引。然后我们汇总最终名单。请注意,我们将 的项目添加到列表的最末尾,即 a为 1、2、3 等的tabIndex="0"项目之后。tabIndex

对于一个完整的工作示例,您可以使用“enter”键进行切换,请查看此fiddle


Nat*_*van 5

Tabbable是一个小型 JS 包,它为您提供按 T​​ab 键顺序排列的所有 Tabbable 元素的列表。因此,您可以在该列表中找到您的元素,然后专注于下一个列表条目。

该包正确处理了其他答案中提到的复杂边缘情况(例如,没有祖先可以是display: none)。而且它不依赖于 jQuery!

在撰写本文时(版本 1.1.1),它有一个警告,即它不支持 IE8,并且浏览器错误会阻止它contenteditable正确处理。