เนโครแมนซิ่ง.
ฉันมี 0-tabIndexes จำนวนหนึ่งซึ่งฉันต้องการนำทางด้วยแป้นพิมพ์
เนื่องจากในกรณีนั้นมีเพียง ORDER ขององค์ประกอบเท่านั้นที่มีความสำคัญฉันจึงใช้มันdocument.createTreeWalker
ก่อนอื่นให้สร้างตัวกรอง (คุณต้องการเฉพาะองค์ประกอบ [มองเห็นได้] ซึ่งมีแอตทริบิวต์ "tabIndex" ที่มีค่าเป็นตัวเลข
จากนั้นคุณตั้งค่าโหนดรูทซึ่งคุณไม่ต้องการค้นหา ในกรณีของฉันthis.m_treeคือ ul-element ที่มีต้นไม้ที่สลับได้ หากคุณต้องการเอกสารทั้งหมดแทนเพียงแทนที่ด้วยthis.m_treedocument.documentElement
จากนั้นคุณตั้งค่าโหนดปัจจุบันเป็นองค์ประกอบที่ใช้งานอยู่ปัจจุบัน:
ni.currentNode = el;
แล้วคุณจะกลับมาหรือni.nextNode()ni.previousNode()
หมายเหตุ:
สิ่งนี้จะไม่ส่งคืนแท็บตามลำดับที่ถูกต้องหากคุณมี tabIndices! = 0 และลำดับองค์ประกอบไม่ใช่ลำดับ tabIndex ในกรณีของ tabIndex = 0 tabOrder จะเป็นลำดับองค์ประกอบเสมอซึ่งเป็นเหตุผลว่าทำไมจึงใช้งานได้ (ในกรณีนั้น)
protected createFilter(fn?: (node: Node) => number): NodeFilter
{
function acceptNode(node: Node): number
{
return NodeFilter.FILTER_ACCEPT;
}
if (fn == null)
fn = acceptNode;
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-loop
while (currentNode = ni.nextNode())
{
return <HTMLElement>currentNode; // everything is already filtered down to what we need here
}
จะมีเฉพาะในกรณีที่คุณต้องการหากคุณมีเกณฑ์เพิ่มเติมซึ่งคุณไม่สามารถกรองในตัวกรองที่ส่งผ่านไปยัง createTreeWalker
โปรดทราบว่านี่คือ TypeScript คุณต้องลบโทเค็นทั้งหมดที่อยู่หลังเครื่องหมายโคลอน (:) และระหว่างวงเล็บเหลี่ยม (<>) เช่น<Element>หรือ:(node: Node) => numberเพื่อรับ JavaScript ที่ถูกต้อง
นี่เป็นบริการ JS ที่โปร่งใส:
"use strict";
function createFilter(fn) {
function acceptNode(node) {
return NodeFilter.FILTER_ACCEPT;
}
if (fn == null)
fn = acceptNode;
const safeFilter = fn;
safeFilter.acceptNode = fn;
return safeFilter;
}
function createTabbingFilter() {
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;
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;
return NodeFilter.FILTER_ACCEPT;
}
return createFilter(acceptNode);
}
function getNextTab(el) {
let currentNode;
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 = "";?