仅使用文本定位最后一级元素

时间:2018-02-19 16:29:02

标签: javascript jquery text attributes tabindex

我正在尝试将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#这种情况有问题(首先关注div然后关注p所以“示例文字”阅读两次)

    <div>
        <p>Example text</p>
    </div>

--> <div tabindex="0">
        <p tabindex="0">Example text</p>
    </div>

2#此案例更有问题(“第一文字第二文字”再读“第二文字”)

<div tabindex="0">First text
    <p tabindex="0">Second text</p>
</div>

我希望先读取“第一个文本”,然后再读取“第二个文本”。

我有很多解决方案但是沉重而且不合时宜。如果你有一个简单的,请提前感谢你!

基本上,我想仅在带有文本的TAG上应用tabindex,除非它是文本格式化标签(b,i,u,strong ...)。例如:

<div>
  <p tabindex="0">This is <b>great</b> !</p>
</div>

1 个答案:

答案 0 :(得分:1)

从我能读到你的问题,听起来主要的问题是jQuery的text()函数在元素具有子元素的情况下返回太多文本。您特别希望能够在以下示例中选择与“bar”分开的“f​​oo”和“baz”:

<div>foo<p>bar</p>baz</div>

如果是这种情况,那么您需要停止使用“元素”并开始使用Nodes。节点更细粒度,让您更深入地了解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>