如何通过DOM

时间:2017-04-29 06:10:16

标签: javascript jquery dom

我正在为我的网络应用构建键盘访问库。要提示应按下哪些键,我想在链接中加下键。 E.g。

  

O rders --- nvoices --- Ope n 事件

对于纯文本片段,这很容易(这里使用jQuery):

part.html(part.html().replace(new RegExp(key, 'i'), '<u>$&</u>'));

但如果part内有任何html标记,这会破坏性。是否有一种优雅的方式来更新文本节点而永远不会标记?

澄清:我的用例是数百个嵌套模板服务器端生成HTML。目前手动添加accesskey属性。导致像<a href="angebote.html" accesskey="t"><i class="fa fa-fw fa-podcast"></i>Ange<b>bote</b></a>这样的事情。然后,Javascript前端脚本会添加键绑定并尝试为绑定键加下划线。

3 个答案:

答案 0 :(得分:2)

要仅访问文本节点,并在那里进行替换,您可以使用树步行器。我还会创建一个函数来隔离span元素中找到的字母并返回它。然后你可以使用jQuery(或其他任何方法)来装饰你想要的元素:

function getLetter(elem, letter){
    if (elem.get) elem = elem.get(0); // remove jQuery wrapper
    var nodes = document.createTreeWalker(elem, NodeFilter.SHOW_TEXT, null, null),
        $node, text, pos, $span;
    letter = letter.toLowerCase();
    while ($node = $(nodes.nextNode())) {
        text = $node.text();
        pos = text.toLowerCase().indexOf(letter);
        if (pos > -1) {
            $span = $('<span>').text(text[pos]);
            $node.replaceWith( // separate the letter from the other text
                text.substr(0, pos),
                $span,
                text.substr(pos+1)
            );
            return $span; // return the element that just has that one letter
        }
    }
}

getLetter($('#orders'), 'o').addClass('underline');
getLetter($('#invoices'), 'i').addClass('underline');
getLetter($('#incidents'), 'n').addClass('underline');
.underline { text-decoration: underline }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h3>Some mix of HTML:</h3>
<div id="orders">
    <span style="color: purple">Order<i>(s)</i></span>
</div>
<div id="invoices">
    <ul><li><b>!!</b>Invoices <i>(urgent)</i></li></ul>
</div>
<div id="incidents">
    <table style="border: 1px solid"><tr><td>Open</td><td>incidents</td></tr></table>
</div>

功能说明

该函数有两个参数:

  • elem:包含需要搜索的文本的容器元素。此元素可能有也可能没有嵌套的HTML标记。
  • letter:要在该元素中识别的字母:只有该字母的第一次出现才会起作用。

该函数返回:

  • undefined当没有匹配时,即所提供的元素包含的任何文本中不会出现提供的字母。
  • 该函数创建的新span元素:它将包含找到的字母。其余文本放在该新元素之前和之后的单独文本节点中。

答案 1 :(得分:1)

对于单个字母,range API应该是微不足道的,因为它们不会被分割为多个嵌套节点。

let range = document.createRange();
let div = document.createElement("div")
div.textContent = "Orders --- Invoices --- Open Incidents"
let textNode = div.firstChild

let underline = document.createElement("u")

range.setStart(textNode, 0);
range.setEnd(textNode, 1);
range.surroundContents(underline);
console.log(div.outerHTML)
// <div><u>O</u>rders --- Invoices --- Open Incidents</div>

答案 2 :(得分:0)

[].forEach.call(document.getElementsByTagName('a'),function(el){  
     el.innerHTML=el.innerHTML.replace(el.getAttribute('acceskey'), 
     '<u>'+el.getAttribute('acceskey')+'</u>')  
 })

在此处试试:JS FIddle