네크 로맨싱.
키보드로 탐색하고 싶은 0-tabIndexes가 많이 있습니다.
이 경우 요소의 순서 만 중요했기 때문에document.createTreeWalker
따라서 먼저 필터를 만듭니다 (NUMERICAL 값이있는 "tabIndex"속성이있는 [표시] 요소 만 필요합니다.
그런 다음 검색하지 않으려는 루트 노드를 설정합니다. 제 경우 this.m_tree
에는 전환 가능한 트리를 포함하는 ul 요소입니다. 대신 전체 문서를 원하는 경우에, 다만 교체 this.m_tree
와 함께document.documentElement
.
그런 다음 현재 노드를 현재 활성 요소로 설정합니다.
ni.currentNode = el; // el = document.activeElement
그런 다음 ni.nextNode()
또는 ni.previousNode()
.
참고 :
tabIndices! = 0이 있고 요소 순서가 tabIndex 순서가 아닌 경우 탭이 올바른 순서로 반환되지 않습니다. tabIndex = 0 인 경우 tabOrder는 항상 요소 순서이므로 이것이 작동합니다 (이 경우).
protected createFilter(fn?: (node: Node) => number): NodeFilter
{
// Accept all currently filtered elements.
function acceptNode(node: Node): number
{
return NodeFilter.FILTER_ACCEPT;
}
if (fn == null)
fn = acceptNode;
// Work around Internet Explorer wanting a function instead of an object.
// IE also *requires* this argument where other browsers don't.
const safeFilter: NodeFilter = <NodeFilter><any>fn;
(<any>safeFilter).acceptNode = fn;
return safeFilter;
}
protected createTabbingFilter(): NodeFilter
{
// Accept all currently filtered elements.
function acceptNode(node: Node): number
{
if (!node)
return NodeFilter.FILTER_REJECT;
if (node.nodeType !== Node.ELEMENT_NODE)
return NodeFilter.FILTER_REJECT;
if (window.getComputedStyle(<Element>node).display === "none")
return NodeFilter.FILTER_REJECT;
// "tabIndex": "0"
if (!(<Element>node).hasAttribute("tabIndex"))
return NodeFilter.FILTER_SKIP;
let tabIndex = parseInt((<Element>node).getAttribute("tabIndex"), 10);
if (!tabIndex || isNaN(tabIndex) || !isFinite(tabIndex))
return NodeFilter.FILTER_SKIP;
// if ((<Element>node).tagName !== "LI") return NodeFilter.FILTER_SKIP;
return NodeFilter.FILTER_ACCEPT;
}
return this.createFilter(acceptNode);
}
protected getNextTab(el: HTMLElement): HTMLElement
{
let currentNode: Node;
// https://developer.mozilla.org/en-US/docs/Web/API/Document/createNodeIterator
// https://developer.mozilla.org/en-US/docs/Web/API/Document/createTreeWalker
// let ni = document.createNodeIterator(el, NodeFilter.SHOW_ELEMENT);
// let ni = document.createTreeWalker(this.m_tree, NodeFilter.SHOW_ELEMENT);
let ni = document.createTreeWalker(this.m_tree, NodeFilter.SHOW_ELEMENT, this.createTabbingFilter(), false);
ni.currentNode = el;
while (currentNode = ni.nextNode())
{
return <HTMLElement>currentNode;
}
return el;
}
protected getPreviousTab(el: HTMLElement): HTMLElement
{
let currentNode: Node;
let ni = document.createTreeWalker(this.m_tree, NodeFilter.SHOW_ELEMENT, this.createTabbingFilter(), false);
ni.currentNode = el;
while (currentNode = ni.previousNode())
{
return <HTMLElement>currentNode;
}
return el;
}
while 루프는
while (currentNode = ni.nextNode())
{
// Additional checks here
// if(condition) return currentNode;
// else the loop continues;
return <HTMLElement>currentNode; // everything is already filtered down to what we need here
}
createTreeWalker에 전달 된 필터에서 필터링 할 수없는 추가 기준이있는 경우에만 원하는 경우에만 있습니다.
이것은 TypeScript입니다. 콜론 (:) 뒤와 꺾쇠 괄호 (<>) 사이의 모든 토큰을 제거해야합니다 (예 : <Element>
또는:(node: Node) => number
유효한 자바 스크립트를 얻을 수 있습니다.
여기 서비스로 트랜스 파일 된 JS :
"use strict";
function createFilter(fn) {
// Accept all currently filtered elements.
function acceptNode(node) {
return NodeFilter.FILTER_ACCEPT;
}
if (fn == null)
fn = acceptNode;
// Work around Internet Explorer wanting a function instead of an object.
// IE also *requires* this argument where other browsers don't.
const safeFilter = fn;
safeFilter.acceptNode = fn;
return safeFilter;
}
function createTabbingFilter() {
// Accept all currently filtered elements.
function acceptNode(node) {
if (!node)
return NodeFilter.FILTER_REJECT;
if (node.nodeType !== Node.ELEMENT_NODE)
return NodeFilter.FILTER_REJECT;
if (window.getComputedStyle(node).display === "none")
return NodeFilter.FILTER_REJECT;
// "tabIndex": "0"
if (!node.hasAttribute("tabIndex"))
return NodeFilter.FILTER_SKIP;
let tabIndex = parseInt(node.getAttribute("tabIndex"), 10);
if (!tabIndex || isNaN(tabIndex) || !isFinite(tabIndex))
return NodeFilter.FILTER_SKIP;
// if ((<Element>node).tagName !== "LI") return NodeFilter.FILTER_SKIP;
return NodeFilter.FILTER_ACCEPT;
}
return createFilter(acceptNode);
}
function getNextTab(el) {
let currentNode;
// https://developer.mozilla.org/en-US/docs/Web/API/Document/createNodeIterator
// https://developer.mozilla.org/en-US/docs/Web/API/Document/createTreeWalker
// let ni = document.createNodeIterator(el, NodeFilter.SHOW_ELEMENT);
// let ni = document.createTreeWalker(this.m_tree, NodeFilter.SHOW_ELEMENT);
let ni = document.createTreeWalker(document.documentElement, NodeFilter.SHOW_ELEMENT, createTabbingFilter(), false);
ni.currentNode = el;
while (currentNode = ni.nextNode()) {
return currentNode;
}
return el;
}
function getPreviousTab(el) {
let currentNode;
let ni = document.createTreeWalker(document.documentElement, NodeFilter.SHOW_ELEMENT, createTabbingFilter(), false);
ni.currentNode = el;
while (currentNode = ni.previousNode()) {
return currentNode;
}
return el;
}
currentElementId = "";
있습니까?