Necromancing।
मेरे पास 0-tabIndexes की एक buch है, जिसे मैं कीबोर्ड से नेविगेट करना चाहता था।
चूंकि उस मामले में, केवल तत्वों के ओआरडीआर ने ही बात की, मैंने इसका उपयोग कियाdocument.createTreeWalker
इसलिए पहले आप फ़िल्टर बनाएं (आप केवल [दृश्यमान] तत्व चाहते हैं, जिसमें NUMERICAL मान के साथ एक विशेषता "tabIndex") है।
फिर आप रूट नोड सेट करते हैं, जिसके आगे आप खोजना नहीं चाहते हैं। मेरे मामले में, this.m_tree
एक उल्टा तत्व है जिसमें एक भीगे हुए पेड़ होते हैं। आप पूरे दस्तावेज के बजाय चाहते हैं, बस की जगह 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 (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
}
यदि आप चाहते हैं कि आपके पास अतिरिक्त मानदंड हों तो आप केवल उसे बना सकते हैं जिसे आप फ़िल्टर में फ़िल्टर नहीं कर सकते।
ध्यान दें कि यह टाइपस्क्रिप्ट है, आपको कॉलन (:) और कोण-कोष्ठक (<>) के बीच, <Element>
या :(node: Node) => number
मान्य जावास्क्रिप्ट प्राप्त करने के लिए सभी टोकन हटाने की आवश्यकता है ।
एक सेवा के रूप में, ट्रांसस्पैन्ड जेएस:
"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 = "";
?