Saya baru-baru ini menemukan fungsi seperti ini ketika mengerjakan sebuah proyek: menyorot kata kunci di halaman web.
Saya pikir ini akan menjadi operasi sederhana yang dapat dicapai dengan penggantian innerHTML, tetapi saya menemui banyak masalah. Artikel ini mencatat masalah-masalah tersebut dan solusi akhir yang tepat, semoga dapat bermanfaat bagi teman-teman yang memiliki pengalaman yang sama. Jika Anda hanya tertarik pada hasilnya, abaikan prosesnya dan lewati untuk melihat hasilnya~
Praktik umum: penggantian rutinIde: Jika Anda ingin menyorot elemen, Anda perlu mengekstrak kata kunci dan membungkusnya dalam tag, lalu menyesuaikan gaya tag. Gunakan innerHTML atau outHTML, namun jangan gunakan innerText atau outText.
const regex = RegExp(kata kunci,g)element.innerHTML baru = elemen.innerHTML.replace(regex,<b class=a>+keyword+</b>)element.classList.add(highlight)
Bahaya tersembunyi dari melakukan hal ini adalah sebagai berikut:
()/div<div id=parent> <div class=test>tes</div> </div>
Elemen simpul induk kata kunci melakukan pemrosesan pewarnaan latar belakang melalui kelas, yang mencemari DOM asli sampai batas tertentu dan dapat memengaruhi reposisi elemen. (Sebagai plug-in, kami berharap dapat mengubah DOM asli sesedikit mungkin)
Pengoptimalan reguler: hanya elemen proses yang terletak di dalam tagvar formatKeyword = text.replace(/[-////^$*+?.()|[/]{}]/g, '//$&') // Escape karakter khusus yang terdapat dalam kata kunci, Misalnya, /.var finder = new RegExp(>.*?++.*?<) // Ekstrak teks yang terletak di tag untuk menghindari kesalahan pengoperasian kelas, id, dll. element.innerHTML = element.innerHTML.replace(finder,function(matched){ return matched.replace(text,<br>+text+</br>)})//Ganti kata kunci dalam teks yang diekstraksi di dalam tag
Ini dapat menyelesaikan sebagian besar masalah, tetapi masalah yang masih ada adalah selama ada simbol < yang serupa di atribut tag, aturan pencocokan akan dilanggar dan konten ekstraksi reguler akan salah. jadi karakter khusus ini tidak bisa dihindari.
<div dataset=p>d>Ganti</div>Optimasi Reguler 2: Hapus tag yang mungkin terpengaruh
<div id=keyword>keyword</div> =》Ganti tag penutup dengan variabel [replaced1]keyword[replaced2]//Id=keyword pada tag penutup tidak akan diproses=》[replaced1]<b>keyword </b >[replaced2] =》Ganti variabel sementara yang diganti dengan tag asli <div id=keyword><b>keyword</b></div>
Yang terpenting, metode ini tidak dapat mengekstrak tag dengan benar ketika nilai tag berisi simbol <>.
Singkatnya, setelah N banyak upaya, berbagai situasi belum ditangani secara efektif melalui regularisasi. Lalu saya berubah pikiran dan memprosesnya melalui node, bukan string. element.childNodes dapat membersihkan informasi interferensi dalam tag dengan paling efektif.
[Solusi sempurna] Memproses melalui node DOM<div id=parent> kata kunci 1 <span id=anak> kata kunci 2 </span> </div>
Dapatkan semua node anak melalui parent.childNodes. Node anak dapat diganti dengan innerText.replce(keyword,result)
untuk mendapatkan efek penyorotan yang diinginkan, sebagai berikut: <span id=child><b>keyword</b> 2</span>
(Pemrosesan rekursif: ketika anak Operasi penggantian dilakukan ketika node tidak berisi node anak).
Namun, kata kunci 1 adalah simpul teks dan hanya dapat mengubah konten teks, tidak dapat menambahkan HTML, dan tidak dapat mengontrol gayanya secara mandiri. Node teks tidak dapat diubah menjadi node biasa, yang juga merupakan hal yang paling menyusahkan.
Akhirnya~, inilah fokus artikel ini. Karena fungsi ini, saya melakukan kontak serius dengan node teks untuk pertama kalinya. Dari sini saya menemukan Teks, dan menggunakan metode memotong node teks dan menggantinya untuk mencapai penyorotan.
Kode sumber dan sorotan pemulihan lihat kode sumber
const reg = RegExp baru(kata kunci.replace(/[-////^$*+?.()|[/]{}]/g, '//$&'))highlight = fungsi (node,reg ){ if (node.nodeType == 3) { //Hanya memproses node teks const match = node.data.match(new RegExp(reg)); document.createElement(b); highlightEl.dataset.highlight=y const wordNode = node.splitText(match.index) wordNode.splitText(match[0].length); // Potong menjadi tiga node Teks setelah kata kunci pertama dan const wordNew = document.createTextNode(wordNode.data); highlightEl.appendChild(wordNew);//highlight Node berhasil dibangun wordNode.parentNode.replaceChild(highlightEl, wordNode); // Ganti node teks} } else if (node.nodeType == 1 && node.dataset.highlight!=y ) { for (var i = 0 ; saya < node.childNodes.length; i++) { highlight(node.childNodes[i], reg);Meringkaskan
Di atas adalah solusi sempurna untuk menyorot kata kunci dalam HTML yang diperkenalkan oleh editor. Saya harap ini dapat membantu Anda. Jika Anda memiliki pertanyaan, silakan tinggalkan pesan kepada saya dan editor akan membalas Anda tepat waktu. Saya juga ingin mengucapkan terima kasih kepada semua orang atas dukungan Anda terhadap situs seni bela diri VeVb!