HTMLでキーワードを強調表示するのに最適なソリューション

HTMLでキーワードを強調表示するのに最適なソリューション

最近、プロジェクトに取り組んでいるときに、Web ページ上のキーワードを強調表示する機能に遭遇しました。

innerHTML の置換で実現できる簡単な操作だと思っていましたが、多くの問題に遭遇しました。この記事では、これらの問題と最終的な完璧な解決策を記録し、同じ経験をした友人の役に立つことを願っています。結果だけに興味がある場合は、プロセスを無視して結果に進んでください。

一般的な方法:定期的な交換

アイデア: 要素を強調表示するには、キーワードを抽出してタグで囲み、タグのスタイルを調整する必要があります。 innerText または outText の代わりに innerHTML または outHTML を使用します。

const regex = 新しい RegExp(キーワード、"g")
element.innerHTML = element.innerHTML.replace(正規表現、"<b class="a">"+キーワード+"</b>")
element.classList.add("ハイライト")

これを行うと、次のような隠れた危険が生じます。

()\
分割
<div id="親">
    <div class="test">テスト</div>
  </div>

キーワード親ノード要素は、クラスを使用して背景色付けを実行します。これにより、元の DOM がある程度汚染され、要素の再配置に影響する可能性があります。 (プラグインなので、元のDOMをできるだけ変更しないことが望まれます)

通常の最適化1: タグ内の要素のみを処理する

var formatKeyword = text.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') // キーワードに含まれる / などの特殊文字をエスケープします。
var finder = new RegExp(">.*?"++".*?<") // クラスやIDなどの誤操作を避けるためにタグ内のテキストを抽出します。 element.innerHTML = element.innerHTML.replace(finder,function(matched){
        matched.replace(text,"<br>"+text+</br>) を返します
}) // 抽出したタグテキスト内のキーワードを置き換える

これでほとんどの問題は解決できますが、タグ属性に < のような記号がある限り、一致ルールが破られ、通常の抽出コンテンツが不正確になるという問題がまだ残っています。HTML5 データセットは任意のコンテンツをカスタマイズできるため、これらの特殊文字は避けられません。

<div dataset="p>d">置換</div>

通常の最適化2: 影響を受ける可能性のあるラベルをクリアする

<div id="keyword">キーワード</div>
  =》終了タグを変数 [replaced1] キーワード [replaced2] に置き換えます // 終了タグ内の id="keyword" は処理されません =》
  [置換1]<b>キーワード</b>[置換2]
  =》一時変数を元のタグ <div id="keyword"><b>keyword</b></div> に置き換えます
  • このアイデアとソースコードはここから来ていますが、問題は次のとおりです:
  • [replaced1]にキーワードが含まれている場合、置換中に例外が発生します。

最も重要なことは、タグ値に <> 記号が含まれている場合、この方法ではタグを正しく抽出できないことです。

つまり、多くの試行を経ても、正規表現はさまざまな状況を効果的に処理することができませんでした。その後、考え方を変えて、文字列ではなくノードを通じて処理するようになりました。 element.childNodes は、タグ内のノイズ情報を最も効果的にクリーンアップできます。

[完璧な解決策] DOMノードを介した処理

<div id="親">
    キーワード1
  <span id="子">
    キーワード2
  </span>
 </div>

parent.childNodes を通じてすべての子ノードを取得します。次のように、子ノードをinnerText.replce(keyword,result)で置き換えて、目的の強調表示効果を得ることができます: <span id="child"><b>keyword</b> 2</span> (再帰処理: 子ノードに子ノードが含まれていない場合は置き換えます)。

ただし、キーワード 1 はテキスト ノードであり、テキスト コンテンツを変更することしかできず、HTML を追加することはできず、そのスタイルを個別に制御することもできません。そして、テキストノードは通常のノードに変換できないため、これが最も厄介な点です。

最後に、この記事の焦点はここにあります。この機能のおかげで、私は初めてテキストノードについて真剣に知るようになりました。ここからテキストが検出され、テキスト ノードを切り取って置き換えることで強調表示が実現されます。

ソースコードとハイライトの復元、ソースコードを参照

const reg = new RegExp(keyword.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'))
ハイライト = 関数 (ノード、reg){
    if (node.nodeType == 3) { //テキストノードのみ処理 const match = node.data.match(new RegExp(reg));
        (一致)の場合{
          const highlightEl = document.createElement("b");
          highlightEl.dataset.highlight="y"
          定数 wordNode = node.splitText(match.index)
          wordNode.splitText(match[0].length); // 最初のキーワードと最後の3つのテキストノードに分割します。const wordNew = document.createTextNode(wordNode.data);
          highlightEl.appendChild(wordNew);//ハイライトノードが正常に構築されました wordNode.parentNode.replaceChild(highlightEl, wordNode);//テキストノードを置き換えます}
    } そうでない場合 (node.nodeType == 1 && node.dataset.highlight!="y"
    ){
        (var i = 0; i < node.childNodes.length; i++) {
            ハイライト(node.childNodes[i], reg);
            私は++
        }
    }  
}

要約する

上記は、HTML でキーワードを強調表示するための完璧なソリューションです。お役に立てれば幸いです。ご質問がある場合は、メッセージを残してください。すぐに返信いたします。また、123WORDPRESS.COM ウェブサイトをサポートしてくださっている皆様にも感謝申し上げます。

<<:  モバイル開発におけるHTML5開発の現状を深く理解する

>>:  CentOS7にsshをインストールして設定する

推薦する

MySQL 集計統計データの低速クエリの最適化

前面に書かれた注文テーブル、アクセス記録テーブル、商品テーブルなど、日常生活でデータベースを操作する...

Vue px to rem 構成の詳細な説明

目次方法1 1. 構成とインストールの手順:方法2方法3要約する方法1 1. 構成とインストールの手...

カルーセル効果を作成するためのjs

カルーセルはフロントエンド開発において比較的重要なポイントだと思います。ネイティブjsの知識ポイント...

jsはCanvasを使用して複数の画像を1つの実装コードにマージします

解決 関数 mergeImgs(リスト) { const imgDom = document.cre...

union (all) と limit および exists キーワードの使用法を理解するための MySQL シリーズチュートリアル

目次1.union: クエリ結果を追加できます1) すべてを結合: 重複を削除できません2) ユニオ...

MySQL 最適化チュートリアル: 大規模なページングクエリ

目次背景制限の最適化最適化方法1. カバーインデックスを使用する2. サブクエリの最適化3. 遅延連...

WeChatミニプログラムは同時通訳を利用して音声認識を実装します

私は同時通訳音声認識機能を使用して、WeChatアプレットのホームページの音声検索機能を実現しました...

Vueデータプロキシの詳細な説明

目次1. これからお話しするのは、フロントエンド担当者がvue-cliで完了できるソリューション、デ...

複数の例で HTML フォームを使用する方法

参考までに、HTMLフォームの使い方を9つの簡単な例で分析します。具体的な内容は次のとおりです。 1...

NodeJSのモジュール性に関する詳細な説明

目次1. はじめに2. 本文2.1 モジュールとは何ですか? 2.2 解決2.3、require.r...

CentOS 7 に MySQL 8.0.20 データベースをインストールするための詳細なチュートリアル

関連記事: MySQL8.0.20 インストール チュートリアルとインストールの問題に関する詳細なチ...

Vue codemirrorはオンラインコードコンパイラの効果を実現します

序文Web 上でオンライン コード コンパイルの効果を実現したい場合は、 CodeMirrorを再度...

MySQLコマンドラインでSQLファイルを実行するいくつかの方法

目次最初の方法: MySQLデータベースが接続されていない場合2 番目の方法: データベースがすでに...

Ubuntu で中国語入力方法が使えない場合の解決策

Ubuntu では中国語入力方法の解決策はありません。仮想マシンや Ubuntu システムをインスト...

nginx を使用して静的リソース サーバーを構築する方法

Windows を例にとると、Linux も実際には同じです。静的リソースサーバーを構築するパソコン...