[javascript] 탭 인덱스에서 다음 요소에 초점 맞추기

포커스가있는 현재 요소를 기반으로 탭 시퀀스의 다음 요소로 포커스를 이동하려고합니다. 지금까지 검색에서 아무것도 찾지 못했습니다.

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

    currentElementId = "";
    currentElement.nextElementByTabIndex.focus();
}

물론 nextElementByTabIndex가 이것이 작동하는 핵심 부분입니다. 탭 시퀀스에서 다음 요소를 어떻게 찾습니까? 솔루션은 JQuery와 같은 것이 아니라 JScript를 기반으로해야합니다.



답변

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;
        }
    }
}


답변

나는 이것을 구현 한 적이 없지만 비슷한 문제를 조사했으며 여기에 내가 시도 할 것입니다.

먼저 시도

당신은 단순히 수 있다면 첫째, 나는 볼 것이다 화재 keypress이벤트를 현재 포커스가있는 요소에 탭 키를. 브라우저마다이 작업을 수행하는 다른 방법이있을 수 있습니다.

그래도 안된다면 더 열심히해야합니다 …

jQuery 구현을 참조하려면 다음을 수행해야합니다.

  1. Tab 및 Shift + Tab 듣기
  2. 탭 가능한 요소 파악
  3. 탭 순서 작동 방식 이해

1. Tab 및 Shift + Tab 듣기

Tab 및 Shift + Tab 듣기는 웹의 다른 곳에서 잘 다루어 질 수 있으므로 해당 부분을 건너 뛰겠습니다.

2. 탭 가능한 요소 파악

탭이 가능한 요소를 아는 것은 더 까다 롭습니다. 기본적으로 요소는 포커스가 있고 속성이 tabindex="-1"설정 되지 않은 경우 탭이 가능합니다 . 따라서 어떤 요소가 초점을 맞출 수 있는지 물어봐야합니다. 다음 요소에 초점을 맞출 수 있습니다.

  • input, select, textarea, button, 및 object요소 해제되지 않은.
  • a및 세트에 대한 숫자 값이 있거나있는 area요소 .hreftabindex
  • tabindex세트에 대한 숫자 값이있는 모든 요소 .

또한 다음과 같은 경우에만 요소에 초점을 맞출 수 있습니다.

  • 그 조상은 없습니다 display: none.
  • 의 계산 된 값은 visibility입니다 visible. 즉, visibility설정 한 가장 가까운 조상 은 값이이어야합니다 visible. 조상이 visibility설정 되지 않은 경우 계산 된 값은 visible입니다.

자세한 내용은 다른 Stack Overflow 답변에 있습니다.

3. 탭 순서 작동 방식 이해

문서에있는 요소의 탭 순서는 tabindex속성에 의해 제어됩니다 . 값이 설정되지 않은 경우은 tabindex사실상 0입니다.

tabindex문서 의 순서는 1, 2, 3,…, 0입니다.

처음에 body요소 (또는 요소 없음)에 포커스가 있을 때 탭 순서의 첫 번째 요소는 0이 아닌 가장 낮은 요소입니다 tabindex. 여러 요소가 동일한 tabindex경우 마지막 요소에 도달 할 때까지 문서 순서대로 이동합니다 tabindex. 그런 다음 다음으로 낮은 값으로 이동 tabindex하고 프로세스가 계속됩니다. 마지막으로 0 (또는 비어 있음)으로 해당 요소로 마무리 tabindex합니다.


답변

이 목적을 위해 내가 만든 것입니다.

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();
        }
    }
}

풍모:

  • 구성 가능한 포커스 가능 요소 집합
  • jQuery가 필요하지 않습니다.
  • 모든 최신 브라우저에서 작동
  • 빠르고 가벼운

답변

이 작업을 수행하는 간단한 jQuery 플러그인 을 만들었습니다 . jQuery UI의 ‘: tabbable’선택기를 사용하여 다음 ‘tabbable’요소를 찾아 선택합니다.

사용 예 :

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


답변

대답의 핵심은 다음 요소를 찾는 데 있습니다.

  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];
  }

용법:

var nextEl = findNextTabStop(element);
nextEl.focus();

우선 순위를 지정하는 데 관심이 없습니다 tabIndex.


답변

위의 주석에서 언급했듯이 어떤 브라우저도 탭 순서 정보를 노출하지 않는다고 생각합니다. 다음은 탭 순서에서 다음 요소를 가져 오기 위해 브라우저가 수행하는 작업의 단순화 된 근사치입니다.

var allowedTags = {input: true, textarea: true, button: true};

var walker = document.createTreeWalker(
  document.body,
  NodeFilter.SHOW_ELEMENT,
  {
    acceptNode: function(node)
    {
      if (node.localName in allowedTags)
        return NodeFilter.FILTER_ACCEPT;
      else
        NodeFilter.FILTER_SKIP;
    }
  },
  false
);
walker.currentNode = currentElement;
if (!walker.nextNode())
{
  // Restart search from the start of the document
  walker.currentNode = walker.root;
  walker.nextNode();
}
if (walker.currentNode && walker.currentNode != walker.root)
  walker.currentNode.focus();

이것은 일부 태그 만 고려하고 tabindex속성을 무시 하지만 달성하려는 것에 따라 충분할 수 있습니다.


답변

tabIndex요소 의 속성을 확인하여 초점을 맞출 수 있는지 확인할 수있는 것 같습니다 . 초점을 맞출 수없는 요소 tabindex는 “-1″입니다.

그런 다음 탭 중지에 대한 규칙을 알아야합니다.

  • tabIndex="1" 우선 순위가 가장 높습니다.
  • tabIndex="2" 다음으로 높은 우선 순위가 있습니다.
  • tabIndex="3" 다음입니다.
  • tabIndex="0" (또는 기본적으로 탭 가능) 우선 순위가 가장 낮습니다.
  • tabIndex="-1" (또는 기본적으로 탭할 수 없음)은 탭 정지 역할을하지 않습니다.
  • tabIndex가 동일한 두 요소의 경우 DOM에서 가장 먼저 나타나는 요소가 더 높은 우선 순위를 갖습니다.

다음은 순수 자바 스크립트를 사용하여 순서대로 탭 정지 목록을 작성하는 방법의 예입니다.

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]);
}

먼저 DOM을 살펴보고 인덱스와 함께 모든 탭 정지를 순서대로 수집합니다. 그런 다음 최종 목록을 조합합니다. tabIndex="0"목록 맨 끝에 있는 항목을 추가합니다 .tabIndex 1, 2, 3 등

“enter”키를 사용하여 탭할 수있는 완전히 작동하는 예제는이 fiddle을 확인하십시오 .