仅针对带有文本的最后一级元素
Target only last level element with text
我正在尝试将 tabindex="0"
应用于一堆元素:
- 里面有文字
- 还没有
tabindex
。
这是我的代码:
$(elems).not("[disabled]").each(function() {
let n = $(this).attr('tabindex');
if ((typeof n == typeof undefined || n == !1) && ($(this).text().trim().length)) {
$(this).attr('tabindex', '0')
}
});
用户是盲人,用TAB
翻页,用语音合成阅读文字。
1#这个案例还可以
<div>Example text</div>
--> <div tabindex="0">Example text</div>
2#这个case有问题(先关注div
再关注p
所以"Example text"看了两遍)
<div>
<p>Example text</p>
</div>
--> <div tabindex="0">
<p tabindex="0">Example text</p>
</div>
2#这种情况比较有问题("First text Second text"再读一遍"Second text")
<div tabindex="0">First text
<p tabindex="0">Second text</p>
</div>
我希望先阅读 "First text",然后阅读 "Second text"。
我有很多解决方案,但都很繁琐。如果你有一个简单的,提前谢谢你!
基本上,我只想在带有文本的 TAG 上应用 tabindex,除非它是文本格式选项卡 (b、i、u、strong...)。示例:
<div>
<p tabindex="0">This is <b>great</b> !</p>
</div>
根据我对您问题的了解,听起来主要问题是 jQuery 的 text()
函数在元素具有子元素的情况下返回过多文本。在以下示例中,您特别希望能够将 "foo" 和 "baz" 与 "bar" 分开:
<div>foo<p>bar</p>baz</div>
如果是这种情况,那么您需要停止使用 "elements" 并开始使用 Nodes。节点更多 fine-grained,让您更深入地了解 DOM 的实际情况。比如上面会被解析成大致如下的节点树:
element: div
text: "foo"
element: p
text: "bar"
text: "baz"
节点更难处理,因为有更多不同类型和不同特性的节点。不过,当您需要更多控制时,这是您通常必须承担的成本。
这是您可以如何实现目标的一个示例,但您可能需要根据自己的具体需求对其进行调整。
var root = document.getElementById('root');
processChildNodes( root );
// Log the resulting HTML to the console
// so that we can see the tab index attribute:
console.log( root.innerHTML );
function processChildNodes(parent){
var child;
// Get either the first child of the parent or the next sibling of
// the current child.
// If we don't have any children or we run out of siblings, then
// we're done here.
while ( child = child ? child.nextSibling : parent.firstChild ){
// If the node is disabled, then skip it.
// Maybe this should be data-disabled?
switch (child.nodeType){
case Node.ELEMENT_NODE:
// If the current node is an element, then set the tabIndex
// and process the children.
if ( !child.hasAttribute('disabled') ){
child.setAttribute( 'tabindex', '0' );
processChildNodes( child );
}
break;
case Node.TEXT_NODE:
// If the current node is text, then "read" the text.
// You don't have an example of how this is supposed to work,
// so I'll just print it to the console.
var text = (child.nodeValue || "").trim();
if (text.length > 0) console.log( 'reading: ' + text );
break;
}
}
}
<div id="root">
<div>Example text 1</div>
<div>
<p>Example text 2</p>
</div>
<div>
First text
<p>Second text</p>
Third text
<p>
Fourth text
<span>Fifth text</span>
</p>
<p disabled>
Skip this one.
</p>
</div>
</div>
我正在尝试将 tabindex="0"
应用于一堆元素:
- 里面有文字
- 还没有
tabindex
。
这是我的代码:
$(elems).not("[disabled]").each(function() {
let n = $(this).attr('tabindex');
if ((typeof n == typeof undefined || n == !1) && ($(this).text().trim().length)) {
$(this).attr('tabindex', '0')
}
});
用户是盲人,用TAB
翻页,用语音合成阅读文字。
1#这个案例还可以
<div>Example text</div>
--> <div tabindex="0">Example text</div>
2#这个case有问题(先关注div
再关注p
所以"Example text"看了两遍)
<div>
<p>Example text</p>
</div>
--> <div tabindex="0">
<p tabindex="0">Example text</p>
</div>
2#这种情况比较有问题("First text Second text"再读一遍"Second text")
<div tabindex="0">First text
<p tabindex="0">Second text</p>
</div>
我希望先阅读 "First text",然后阅读 "Second text"。
我有很多解决方案,但都很繁琐。如果你有一个简单的,提前谢谢你!
基本上,我只想在带有文本的 TAG 上应用 tabindex,除非它是文本格式选项卡 (b、i、u、strong...)。示例:
<div>
<p tabindex="0">This is <b>great</b> !</p>
</div>
根据我对您问题的了解,听起来主要问题是 jQuery 的 text()
函数在元素具有子元素的情况下返回过多文本。在以下示例中,您特别希望能够将 "foo" 和 "baz" 与 "bar" 分开:
<div>foo<p>bar</p>baz</div>
如果是这种情况,那么您需要停止使用 "elements" 并开始使用 Nodes。节点更多 fine-grained,让您更深入地了解 DOM 的实际情况。比如上面会被解析成大致如下的节点树:
element: div
text: "foo"
element: p
text: "bar"
text: "baz"
节点更难处理,因为有更多不同类型和不同特性的节点。不过,当您需要更多控制时,这是您通常必须承担的成本。
这是您可以如何实现目标的一个示例,但您可能需要根据自己的具体需求对其进行调整。
var root = document.getElementById('root');
processChildNodes( root );
// Log the resulting HTML to the console
// so that we can see the tab index attribute:
console.log( root.innerHTML );
function processChildNodes(parent){
var child;
// Get either the first child of the parent or the next sibling of
// the current child.
// If we don't have any children or we run out of siblings, then
// we're done here.
while ( child = child ? child.nextSibling : parent.firstChild ){
// If the node is disabled, then skip it.
// Maybe this should be data-disabled?
switch (child.nodeType){
case Node.ELEMENT_NODE:
// If the current node is an element, then set the tabIndex
// and process the children.
if ( !child.hasAttribute('disabled') ){
child.setAttribute( 'tabindex', '0' );
processChildNodes( child );
}
break;
case Node.TEXT_NODE:
// If the current node is text, then "read" the text.
// You don't have an example of how this is supposed to work,
// so I'll just print it to the console.
var text = (child.nodeValue || "").trim();
if (text.length > 0) console.log( 'reading: ' + text );
break;
}
}
}
<div id="root">
<div>Example text 1</div>
<div>
<p>Example text 2</p>
</div>
<div>
First text
<p>Second text</p>
Third text
<p>
Fourth text
<span>Fifth text</span>
</p>
<p disabled>
Skip this one.
</p>
</div>
</div>