Organisasi pencarian di halaman web dalam JavaScript (tanpa jQuery)

Beberapa hari yang lalu saya menerima tugas uji dari perusahaan untuk lowongan Front-end dev. Tentu saja, tugas itu terdiri dari beberapa poin. Tapi sekarang kita akan fokus hanya pada salah satunya - organisasi pencarian di halaman. Yaitu pencarian dangkal oleh teks yang dimasukkan di bidang (analog Ctrl + F di browser). Keunikan penugasan adalah bahwa penggunaan kerangka kerja JS atau pustaka dilarang. Semua menulis dalam JavaScript asli asli .

(Untuk kejelasan, saya akan terus menemani seluruh artikel dengan tangkapan layar dan kode, sehingga Anda dan saya akan mengerti apa yang sedang kita bicarakan pada saat tertentu)

Menemukan solusi


Pikiran pertama: seseorang telah menulis ini dengan tepat, Anda perlu google dan copy-paste. Jadi saya lakukan. Dalam satu jam, saya menemukan dua skrip yang bagus yang pada dasarnya bekerja dengan cara yang sama, tetapi ditulis berbeda. Saya memilih kode yang saya pahami dengan lebih baik dan dimasukkan ke halaman orang tua saya.

Jika ada yang tertarik, saya mengambil kodenya di sini .

Script segera bekerja. Saya pikir masalahnya sudah selesai, tetapi ternyata, tidak ada pelanggaran bagi penulis naskah, ada cacat besar di dalamnya. Script mencari seluruh konten tag ... dan, seperti yang mungkin sudah Anda tebak, ketika mencari kombinasi karakter yang menyerupai tag atau atributnya, seluruh halaman HTML pecah.

Mengapa skrip tidak berfungsi dengan benar?


Semuanya sederhana. Script berfungsi sebagai berikut. Pertama, kami menuliskan seluruh konten tag tubuh ke dalam variabel, lalu mencari kecocokan dengan ekspresi reguler (pengguna menyetelnya saat memasukkan ke dalam bidang teks) dan kemudian kami mengganti semua kecocokan dengan kode berikut:

 <span style="background-color: yellow;">... ...</span> 

Dan kemudian kami mengganti tag tubuh saat ini dengan yang baru diterima. Markup diperbarui, gaya berubah dan semua hasil yang ditemukan disorot dengan warna kuning di layar.

Anda mungkin sudah mengerti apa masalahnya, tetapi saya akan menjelaskan lebih detail. Bayangkan memasukkan kata "div" di kotak pencarian. Seperti yang Anda mengerti, di dalam tubuh ada banyak tag lain, termasuk div . Dan jika kita semua menerapkan gaya yang disebutkan di atas ke "div" , maka ini tidak akan menjadi blok, tetapi tidak jelas apa, karena desainnya rusak. Akibatnya, setelah menimpa markup, kami mendapatkan halaman web yang benar-benar rusak. Ini terlihat seperti ini.

Itu sebelum pencarian: unggah foto ke Internet Benar-benar memudar
Itu menjadi setelah pencarian: unggah foto secara gratis Benar-benar memudar

Seperti yang Anda lihat, halaman tersebut benar-benar rusak. Singkatnya, skrip tersebut ternyata tidak beroperasi, dan saya memutuskan untuk menulis sendiri dari awal, yang merupakan artikel ini.

Jadi kami menulis skrip dari awal


Bagaimana semuanya terlihat bagiku.



Sekarang kami tertarik dengan formulir pencarian. Dia mengitarinya dengan garis merah.

Mari kita lihat sedikit. Saya menerapkan ini sebagai berikut (sejauh HTML murni). Formulir dengan tiga tag.

Yang pertama adalah untuk memasukkan teks;
Yang kedua - untuk membatalkan pencarian (batalkan pilihan);
Yang ketiga adalah untuk pencarian (sorot hasil yang ditemukan).

 <form> <input type="text" value="" placeholder="Search" autofocus> <input type="button" value=" " title=" "> <input type="submit" value=" " title=" "> </form> 

Jadi, kami memiliki bidang input dan 2 tombol. Saya akan menulis JavaScript di js.js. Misalkan Anda telah membuat dan menghubungkannya.

Hal pertama yang akan kita lakukan: mendaftarkan panggilan fungsi ketika Anda mengklik tombol pencarian dan tombol batal. Ini akan terlihat seperti ini:

 <form> <input class="place_for_search" type="text" id="text-to-find" value="" placeholder="Search" autofocus> <input class="button_for_turn_back" type="button" onclick="javascript: FindOnPage('text-to-find',false); return false;" value=" " title=" "> <input class="button_for_search" type="submit" onclick="javascript: FindOnPage('text-to-find',true); return false;" value=" " title=" "> </form> 

Mari kita jelaskan sedikit apa yang ada di sini dan mengapa.

Kami memberikan bidang teks id = "text-to-find" ( id ini akan merujuk ke elemen dari js ).

Kami memberi tombol batal atribut berikut: type = "button" onclick = "javascript: FindOnPage ('text-to-find', false); return false; "

- Ketik: tombol
- Saat ditekan, fungsi FindOnPage disebut ('text-to-find', false); dan melewati id bidang dengan teks, false

Kami memberikan tombol pencarian atribut berikut: type = "button" onclick = "javascript: FindOnPage ('text-to-find', true); return false; "

- Ketik: kirim (bukan tombol karena di sini Anda dapat menggunakan Enter setelah memasukkan bidang, atau Anda dapat menggunakan tombol juga)
- Saat ditekan, fungsi FindOnPage disebut ('text-to-find', true); dan melewati id bidang dengan teks, true

Anda mungkin memperhatikan satu atribut lagi: true / false . Kami akan menggunakannya untuk menentukan tombol mana yang ditekan (batalkan pencarian atau mulai pencarian). Jika kita klik pada batal, maka berikan false . Jika kita mengklik pencarian, maka berikan true .

OKE, lanjutkan. Buka JavaScript

Kami berasumsi bahwa Anda telah membuat dan menghubungkan file js ke DOM.

Sebelum kita mulai menulis kode, mari kita istirahat dan bahas terlebih dahulu bagaimana semuanya harus bekerja. Yaitu pada intinya, kami akan menulis rencana aksi. Jadi, kita perlu bahwa ketika memasukkan teks di bidang, pencarian dilakukan pada halaman, tetapi tag dan atribut tidak boleh terpengaruh. Yaitu objek teks saja. Cara mencapainya - saya yakin ada banyak cara. Tetapi sekarang kita akan menggunakan ekspresi reguler.

Jadi, ekspresi reguler berikutnya hanya akan mencari jejak teks. ketik: "> ... teks ... <". Yaitu hanya objek teks yang akan dicari, sementara tag dan atribut akan tetap tidak tersentuh.

 />(.*?)</g 

Jadi kita akan menemukan bagian-bagian penting dari kode yang akan kita uraikan dan cari kecocokan dengan teks yang dimasukkan pengguna. Kemudian kita akan menambahkan gaya ke objek yang ditemukan dan setelah itu ganti kode html dengan yang baru.

Mari kita mulai. Pertama, variabel yang kita butuhkan.

 var input,search,pr,result,result_arr, locale_HTML, result_store; //input -  ,    //search -      //pr -     <body></body> //result -    pr (..    ) //result_arr -  pr,      //locale_HTML -  <body></body>    ,     

Dan segera tentukan nilai locale_HTML , terlepas dari apakah kami sedang mencari sesuatu atau tidak. Ini diperlukan untuk segera menyimpan halaman asli dan memiliki kemampuan untuk mengatur ulang gaya.

 var input,search,pr,result,result_arr, locale_HTML, result_store; locale_HTML = document.body.innerHTML; //     body () 

Oke, sekarang ada baiknya membuat fungsi yang dipanggil dari DOM . Segera perkirakan bahwa di dalamnya kita harus memiliki 2 fungsi, yang masing-masing berfungsi tergantung pada tombol yang ditekan. Bagaimanapun, kami melakukan pencarian atau nol. Dan ini dikendalikan oleh atribut benar / salah , seperti yang Anda ingat. Anda juga perlu memahami bahwa ketika Anda mencari lagi, gaya lama harus diatur ulang. Jadi kita mendapatkan yang berikut ini:

 var input,search,pr,result,result_arr, locale_HTML, result_store; locale_HTML = document.body.innerHTML; //     body () function FindOnPage(name, status) { if(status) { FindOnPageBack(); FindOnPageGo(); } //     if(!status) { FindOnPageBack(); } //  } 

Ok, bagian dari logika diimplementasikan, lanjutkan. Penting untuk memeriksa kata yang diterima untuk jumlah karakter. Lagi pula, mengapa kita perlu mencari 1 huruf / simbol. Secara umum, saya memutuskan untuk membatasi ini hingga 3+ karakter.

Jadi, pertama-tama kita mengambil nilai yang dimasukkan pengguna, dan, tergantung pada panjangnya, kami melakukan fungsi pencarian utama, atau fungsi peringatan dan penekanan. Ini akan terlihat seperti ini:

 var input,search,pr,result,result_arr, locale_HTML, result_store; locale_HTML = document.body.innerHTML; //     body () function FindOnPage(name, status) { input = document.getElementById(name).value; //     html if(input.length<3&&status==true) { alert('        '); function FindOnPageBack() { document.body.innerHTML = locale_HTML; } //  } if(input.length>=3) { //  } function FindOnPageBack() { document.body.innerHTML = locale_HTML; } //  if(status) { FindOnPageBack(); FindOnPageGo(); } //     if(!status) { FindOnPageBack(); } //  } 

Sekarang saya akan menjelaskan bagian kode ini. Satu-satunya hal yang tidak jelas adalah baris ini:

function FindOnPageBack () {document.body.innerHTML = locale_HTML; }

Semuanya sederhana di sini: metode innerHTML mengembalikan kode html objek. Dalam hal ini, kami cukup mengganti tubuh saat ini dengan yang asli yang kami simpan saat memuat seluruh halaman.

Kami melanjutkan. Kami memberikan nilai ke variabel utama.

 var input,search,pr,result,result_arr, locale_HTML, result_store; locale_HTML = document.body.innerHTML; //     body () function FindOnPage(name, status) { input = document.getElementById(name).value; //     html if(input.length<3&&status==true) { alert('        '); function FindOnPageBack() { document.body.innerHTML = locale_HTML; } //  } if(input.length>=3) { function FindOnPageGo() { search = '/'+input+'/g'; //     pr = document.body.innerHTML; //     body result = pr.match(/>(.*?)</g); //       result_arr = []; //       () } } function FindOnPageBack() { document.body.innerHTML = locale_HTML; } //  if(status) { FindOnPageBack(); FindOnPageGo(); } //     if(!status) { FindOnPageBack(); } //  } 

Jadi, pada tahap ini, kita sudah memiliki variabel dan nilai utama. Sekarang kita perlu memberikan bagian yang diperlukan dari gaya kode dengan latar belakang yang disorot. Yaitu memeriksa teks yang dipilih untuk ekspresi reguler (pada kenyataannya, teks yang dipilih oleh ekspresi reguler diuraikan oleh ekspresi reguler lagi). Untuk melakukan ini, Anda perlu membuat ekspresi reguler dari teks yang dimasukkan (selesai), dan kemudian jalankan metode yang diteruskan sebagai taktik. Di sini metode eval () akan membantu kita.

Secara umum, setelah kami mengganti teks dan mendapatkan hasilnya dengan gaya, kami perlu mengganti html saat ini dengan yang diterima. Kami melakukannya.

 var input,search,pr,result,result_arr, locale_HTML, result_store; locale_HTML = document.body.innerHTML; //     body () function FindOnPage(name, status) { input = document.getElementById(name).value; //     html if(input.length<3&&status==true) { alert('        '); function FindOnPageBack() { document.body.innerHTML = locale_HTML; } //  } if(input.length>=3) { function FindOnPageGo() { search = '/'+input+'/g'; //     pr = document.body.innerHTML; //     body result = pr.match(/>(.*?)</g); //       result_arr = []; //       () for(var i=0; i<result.length;i++) { result_arr[i] = result[i].replace(eval(search), '<span style="background-color:yellow;">'+input+'</span>'); //  ,        } for(var i=0; i<result.length;i++) { pr=pr.replace(result[i],result_arr[i]) //    html       } document.body.innerHTML = pr; // html  } } function FindOnPageBack() { document.body.innerHTML = locale_HTML; } //  if(status) { FindOnPageBack(); FindOnPageGo(); } //     if(!status) { FindOnPageBack(); } //  } 

Intinya, semuanya sudah siap, dan skrip sudah bekerja. Tetapi tambahkan beberapa detail lebih lanjut untuk kecantikan.

1) Pangkas spasi dalam teks yang dimasukkan pengguna. Masukkan kode ini:

  input = numer.replace(/^\s+/g,''); input = numer.replace(/[ ]{1,}/g,' '); 

Setelah baris ini:

  input = document.getElementById(name).value; //     html 

2) Kami akan memeriksa kebetulan (jika tidak ditemukan kecocokan, kami akan menginformasikan hal ini). Kode ini dimasukkan ke dalam fungsi FindOnPageGo () setelah variabel.

  var warning = true; for(var i=0;i<result.length;i++) { if(result[i].match(eval(search))!=null) { warning = false; } } if(warning == true) { alert('    '); } 

Anda dapat melihat sumbernya di sini .
Anda dapat mengunduh sumbernya di sini .

Sekarang semuanya Tentu saja, Anda dapat menambahkan gulir ke hasil pertama yang ditemukan, pencarian ajax langsung, dan memang Anda dapat meningkatkan tanpa henti. Sekarang ini adalah pencarian yang agak primitif di situs. Tujuan artikel ini adalah untuk membantu pemula jika pertanyaan yang sama muncul dengan saya. Lagi pula, saya tidak menemukan solusi siap pakai yang sederhana.

PS: untuk operasi yang benar, perlu untuk menghapus tanda hubung teks dalam dokumen html di tempat-tempat di mana ada teks biasa di antara tag.

Misalnya, alih-alih

  <p>    </p> 

Harus
  <p>    </p> 

Ini tidak penting, Anda dapat membuang transfer ini secara otomatis pada layanan, tetapi Anda dapat memberi tahu saya pada saat yang sama bagaimana cara memperbaikinya, jika Anda mengerti sebelum saya.

Juga, jika seseorang menulis ini, tetapi dengan pencarian langsung, bagikan sumbernya, itu akan menarik untuk diuraikan.

Saya akan senang mendengar kritik yang membangun, pendapat, dan mungkin rekomendasi.

Baru-baru ini saya menambahkan sedikit kode, melakukan pencarian langsung di halaman. Sehingga pertanyaannya dihapus. Kode HTML tidak berubah. JS bisa lihat di sini .

Pencarian dilakukan menggunakan tag dengan kelas "place_for_live_search". Jadi, agar algoritma menguraikan konten yang diinginkan, tambahkan kelas dan Anda selesai.

Source: https://habr.com/ru/post/id438382/


All Articles