简体   繁体   English

如何在html文档中使用javascript动态处理单词/字符串,然后对其进行标记?

[英]how to dynamically address a word/string with javascript in an html-document and then tag it?

I have an HTML-document: 我有一个HTML文档:

<html>
  <body>
    <p>
      A funny joke:
      <ul>
        <li>do you know why six is afraid of seven?
        <li>because seven ate nine.
      </ul>
      Oh, so funny!
    </p>
  </body>
</html>

Now I want to identify the first occurence of "seven" and tag it with 现在,我要确定“七”的首次出现,并用标记

<span id="link1" class="link">

How can this be accomplished? 如何做到这一点?

Do you have to parse the DOM-tree or is it possible to get the whole code within the body-section and then search for the word? 您是否必须解析DOM树,还是有可能在body-section中获取整个代码,然后搜索单词?

In both cases, after I found the word somewhere, how do you identify it and change it's DOM-parent to span (I guess that's what has to be done) and then add the mentioned attributes? 在这两种情况下,当我在某处找到该词后,如何识别它并更改它的DOM父对象以覆盖范围(我想这是必须要做的),然后添加提及的属性?

It's not so much a code I would expect, but what methods or concepts will do the job. 我所期望的不是代码,而是什么方法或概念可以胜任。

And I am not so much intersted in a framework-solution but in a pure javascript way. 而且我对框架解决方案没有太多的兴趣,而是以纯JavaScript方式进行的。

You need to find a DOM node with type TEXT_NODE (3) and containig your expected word. 您需要找到一个类型为TEXT_NODE(3)的DOM节点,并包含所需的单词。 When you need to split a that node into three ones. 当您需要将该节点拆分为三个节点时。

First is a TEXT_NODE which contains a text before the word you search, second one is a SPAN node containing the word you search, and third one is another TEXT_NODE containing an original node's tail (all after searched word). 第一个是TEXT_NODE,它在您搜索的单词之前包含一个文本,第二个是包含您要搜索的单词的SPAN节点,第三个是另一个包含原始节点尾部的TEXT_NODE(全部在搜索到的单词之后)。

Here is a source code... 这是源代码...

<html>
   <head>
      <style type="text/css">
         .link {
            color: red;
         }
      </style>
   </head>
  <body>
    <p>
      A funny joke:
      <ul>
        <li>do you know why six is afraid of seven?
        <li>because seven ate nine.
      </ul>
      Oh, so funny!
    </p>
    <script type="text/javascript">
       function search(where, what) {
         var children = where.childNodes;
         for(var i = 0, l = children.length; i < l; i++) {
            var child = children[i], pos;
            if(child.nodeType == 3 && (pos = child.nodeValue.indexOf(what)) != -1) { // a TEXT_NODE
               var value = child.nodeValue;
               var parent = child.parentNode;
               var start = value.substring(0, pos);
               var end = value.substring(pos + what.length);
               var span = document.createElement('span');

               child.nodeValue = start;
               span.className = 'link';
               span.id = 'link1';
               span.innerHTML = what;
               parent.appendChild(span);
               parent.appendChild(document.createTextNode(end));
               return true;
            } else
               if(search(child, what))
                  break;
         }
         return false;
       }
       search(document.getElementsByTagName('body')[0], 'seven');
    </script>
  </body>
</html>

This is a function I've written a few years ago that searches for specific text, and highlights them (puts the hits in a span with a specific class name). 这是我几年前写的功能,搜索特定的文本,并强调他们(把命中的span与特定的类名)。

It walks the DOM tree, examining the text content. 它遍历DOM树,检查文本内容。 Whenever it finds a text node containing the looked-for text, it will replace that text node by three new nodes: 只要找到包含查找文本的文本节点,它将用三个新节点替换该文本节点:

  1. one text node with the text preceding the match, 一个文本节点,其文本在匹配项之前,
  2. one (newly created) span element containing the matching text, 一个(新创建的) span元素,其中包含匹配的文本,
  3. and one text node with the text following the match. 一个文本节点,其后的文本为匹配项。

This is the function as I have it. 这就是我所拥有的功能。 It's part of a larger script file, but it should run independently as well. 它是一个较大的脚本文件的一部分,但它也应该独立运行。 (I've commented out a call to ensureElementVisible which made the element visible, since the script also had folding and expanding capabilities). (由于脚本还具有折叠和扩展功能,因此我注释掉了确保元素可见的调用,以ensureElementVisible该元素可见)。

It does one (other) thing that you probably won't need: it turns the search text into a regular expression matching any of the multiple words. 它执行了您可能不需要的另一件事:将搜索文本转换为与多个单词中的任何一个匹配的正则表达式。

function findText(a_text, a_top) {
    // Go through *all* elements below a_top (if a_top is undefined, then use the body)
    //  and check the textContent or innerText (only if it has textual content!)
    var rexPhrase = new RegExp(a_text.replace(/([\\\/\*\?\+\.\[\]\{\}\(\)\|\^\$])/g, '\\$1').replace(/\W+/g, '\\W*')
                                    , 'gi');
    var terms = [];
    var rexSearchTokens = /[\w]+/g;
    var match;
    while(match = rexSearchTokens.exec(a_text)) {
        terms.push(match[0]);
    }
    var rexTerm = new RegExp('\\b(' + terms.join('|') + ')', 'gi');

    var hits = [];
    walkDOMTree(a_top || document.body,
                function search(a_element) {
                    if (a_element.nodeName === '#text') {
                        if(rexPhrase.test(a_element.nodeValue)) {
//                          ensureElementVisible(a_element, true);
                            hits.push(a_element);
                        }
                    }
                });

    // highlight the search terms in the found elements
    for(var i = 0; i < hits.length; i++) {
        var hit = hits[i];
        var parent = hit.parentNode;

        if (parent.childNodes.length === 1) {
            // Remove the element from the hit list
            hits.splice(i, 1);

            var text = hit.nodeValue;
            parent.removeChild(hit);
            var match, prevLastIndex = 0;
            while(match = rexTerm.exec(text)) {
                parent.appendChild(document.createTextNode(text.substr(prevLastIndex, match.index - prevLastIndex)));
                var highlightedTerm = parent.appendChild(document.createElement('SPAN'));
                highlightedTerm.className = 'search-hit';
                highlightedTerm.appendChild(document.createTextNode(match[0]));
                prevLastIndex = match.index + match[0].length;

                // Insert the newly added element into the hit list
                hits.splice(i, 0, highlightedTerm);
                i++;
            }
            parent.appendChild(document.createTextNode(text.substr(prevLastIndex)));

            // Account for the removal of the original hit node
            i--;
        }
    }

    return hits;
}

I found the following so question: Find text string using jQuery? 我发现以下问题: 使用jQuery查找文本字符串?

This appears to be close to what you're trying to do. 这似乎与您要执行的操作接近。 Now are you attempting to wrap just the text "seven" or are you attempting to wrap the entire content of the <li>? 现在,您是在尝试只包装文本“七”,还是在尝试包装<li>的全部内容?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM