0

私は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>

ここで、「7」の最初の出現を識別し、タグを付けたいと思います

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

これはどのように達成できますか?

DOMツリーを解析する必要がありますか、それともbodyセクション内のコード全体を取得してから単語を検索することは可能ですか?

どちらの場合も、どこかで単語を見つけた後、どのようにそれを識別し、そのDOMの親をスパンに変更し(これが行われる必要があると思います)、次に言及された属性を追加しますか?

それは私が期待するほどのコードではありませんが、どのような方法や概念がその仕事をするのでしょうか。

そして、私はフレームワークソリューションにはあまり興味がありませんが、純粋なjavascriptの方法で興味を持っています。

4

3 に答える 3

2

タイプTEXT_NODE(3)のDOMノードを見つけて、予想される単語を含める必要があります。そのノードを3つに分割する必要がある場合。

1つ目は検索する単語の前のテキストを含むTEXT_NODE、2つ目は検索する単語を含むSPANノード、3つ目は元のノードの末尾(すべて検索された単語の後)を含む別のTEXT_NODEです。

これがソースコードです...

<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>
于 2011-03-25T14:33:12.693 に答える
2

これは私が数年前に書いた関数で、特定のテキストを検索し、それらを強調表示します(ヒットをspan特定のクラス名でに入れます)。

DOMツリーをたどり、テキストの内容を調べます。検索されたテキストを含むテキストノードが見つかると、そのテキストノードが3つの新しいノードに置き換えられます。

  1. 一致の前にテキストがある1つのテキストノード、
  2. 一致するテキストを含む1つの(新しく作成された)span要素、
  3. 一致に続くテキストを含む1つのテキストノード。

これは私が持っている機能です。これはより大きなスクリプトファイルの一部ですが、独立して実行する必要もあります。ensureElementVisible(スクリプトには折りたたみ機能と拡張機能もあるため、要素を表示する呼び出しをコメントアウトしました)。

それはおそらくあなたが必要としないであろう一つの(他の)ことをします:それは検索テキストを複数の単語のいずれかに一致する正規表現に変えます。

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;
}
于 2011-03-25T15:21:20.003 に答える
0

私は次のような質問を見つけました: jQueryを使用してテキスト文字列を検索しますか?

これはあなたがやろうとしていることに近いようです。ここで、テキスト「seven」だけをラップしようとしていますか、それとも<li>のコンテンツ全体をラップしようとしていますか?

于 2011-03-23T13:39:04.940 に答える