Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Web Development

Membangun perpustakaan JavaScript pertama Anda

by
Difficulty:IntermediateLength:LongLanguages:

Indonesian (Bahasa Indonesia) translation by Yusuf Samin (you can also view the original English article)

Pernah kagum pada keajaiban Mootools? Pernah bertanya-tanya bagaimana Dojo melakukannya? Pernah ingin tahu tentang jQuery's senam? Dalam tutorial ini, kita akan menyelinap di belakang layar dan mencoba tangan kami dalam membangun versi super sederhana dari perpustakaan favorit Anda.

Kami menggunakan JavaScript library hampir setiap hari. Ketika Anda baru saja akan memulai, memiliki sesuatu seperti jQuery fantastis, terutama karena DOM. Pertama, DOM dapat menjadi agak kasar untuk bertengkar untuk pemula; ini adalah alasan yang cukup buruk untuk API. Kedua, hal ini bahkan tidak konsisten di semua browser.

Kami membungkus elemen dalam suatu objek karena kami ingin dapat membuat metode untuk objek.

Dalam tutorial ini, kita akan mengambil (jelas dangkal) membangun salah satu perpustakaan ini dari awal. Ya, itu akan menyenangkan, tetapi sebelum Anda mendapatkan terlalu bersemangat, izinkan saya mengklarifikasi beberapa poin:

  • ni tidak akan sepenuhnya Perpustakaan dengan fitur lengkap . Oh, kami punya serangkaian metode solid untuk ditulis, tetapi ini bukan jQuery. Kami akan melakukan cukup untuk memberikan perasaan yang baik untuk jenis masalah yang Anda akan mengalami ketika membangun Perpustakaan.
  • Kami tidak akan untuk kompatibilitas browser lengkap di sini. Apa yang kita menulis hari ini harus bekerja pada Internet Explorer 8 +, Firefox 5 +, Opera 10 +, Chrome dan Safari.
  • Kami tidak akan mencakup setiap kemungkinan penggunaan perpustakaan kami. Sebagai contoh, append dan prepend metode hanya akan bekerja jika Anda memasukan instance dari perpustakaan kami; mereka tidak akan bekerja dengan raw DOM node atau nodelists.

Satu hal lagi: sementara kami tidak menulis tes untuk Perpustakaan ini, aku melakukan itu ketika pertama kali mengembangkan ini. Anda bisa mendapatkan Perpustakaan dan tes pada Github.


Langkah 1: Membuat Boilerplate Perpustakaan

Kita akan mulai dengan beberapa kode pembungkus, yang akan berisi seluruh perpustakaan kami. Ini adalah immediately invoked function expression (IIFE)

Seperti yang Anda lihat, kita menyebut perpustakaan kami Dome, karena terutama Perpustakaan DOM. Ya, itu timpang.

Kami punya beberapa hal yang terjadi di sini. Pertama, kita memiliki fungsi; ini akan fungsi konstruktor untuk instance perpustakaan kami; objek-objek akan membungkus elemen yang dipilih atau dibuat.

Kemudian, kita memiliki dome objek, yang sebenarnya Perpustakaan objek; seperti yang Anda lihat, itu dikembalikan di ujung sana. aku punya fungsi get kosong, yang kita akan gunakan untuk memilih elemen dari halaman. Jadi, mari kita mengisinya sekarang.


Langkah 2: Mendapatkan elemen

Fungsi dome.get akan membutuhkan satu parameter, tapi itu bisa sejumlah hal. Jika sebuah string, kita akan menganggap itu adalah suatu CSS selector; tetapi kita juga dapat mengambil DOM Node tunggal, atau NodeList.

Kami menggunakan document.querySelectorAll untuk menyederhanakan penemuan element: Tentu saja, ini membatasi kita dukungan browser, tetapi untuk kasus ini, tidak apa-apa. Jika selector tidak string, kita akan periksa properti length. Jika ada, kita akan tahu kita memiliki NodeList; Sebaliknya, kita memiliki satu elemen dan kami akan menaruh dalam array. Itu karena kita perlu array untuk memasukan ke panggilan kita ke Done di bawah sana; seperti yang Anda lihat, kita baru saja kembali objek Dome baru. Jadi mari kita kembali ke fungsi Dome yang kosong dan Isilah.


Langkah 3: Membuat instance Dome

Berikut adalah fungsi Dome itu:

Saya sangat merekomendasikan Anda menggali di sekitar dalam beberapa perpustakaan favorit Anda.

Ini benar-benar sederhana: kita hanya iterate atas elemen yang kami pilih dan menaruh mereka ke objek baru dengan angka indeks. Kemudian, kita menambahkan properti length.

Tapi apa intinya di sini? Mengapa tidak hanya mengembalikan elemen? Kami membungkus elemen dalam suatu objek karena kami ingin dapat membuat metode untuk objek; ini adalah metode yang akan memungkinkan kita untuk berinteraksi dengan elemen-elemen. Ini adalah benar-benar boiled-down versi jQuery cara melakukannya.

Jadi, sekarang bahwa kita memiliki objek Dome dikembalikan, mari kita tambahkan beberapa metode untuk prototype. Aku akan menaruh metode-metode tepat di bawah Dome fungsi.


Langkah 4: Menambahkan beberapa utilitas

Fungsi pertama yang kita akan menulis adalah fungsi utilitas sederhana. Karena objek Dome kami bisa membungkus lebih dari satu elemen DOM, kita akan perlu loop melalui semua unsur di hampir setiap metode; Jadi, utilitas ini akan berguna.

Mari kita mulai dengan fungsi map:

Tentu saja, map fungsi mengambil parameter tunggal, fungsi callback. Kami akan loop ke item yang dalam array, mengumpulkan apa pun yan dikembalikan dari panggilan callback array results. Perhatikan bagaimana kita memanggil fungsi callback:

Dengan melakukan dengan cara ini, fungsi akan dipanggil dalam konteks contoh Dome kami, dan itu akan menerima dua parameter: elemen saat ini, dan nomor index.

Kami juga ingin fungsi forEach. Ini benar-benar benar-benar sederhana:

Karena satu-satunya perbedaan antara map dan forEach map perlu mengembalikan sesuatu, kita bisa memasukan kami callback ke this.map dan mengabaikan array kembalian; Sebaliknya, kita akan kembalikan this untuk membuat perpustakaan kami chainable. Kita akan menggunakan forEach cukup sedikit. Jadi, perhatikan bahwa ketika kita mengembalikan panggil this.forEach dari fungsi, kita benar-benar mengembalikan this. Sebagai contoh, metode ini benar-benar mengembalikan hal yang sama:

Satu lagi: mapOne. Sangat mudah untuk melihat apakah fungsi ini, tetapi pertanyaan sesungguhnya adalah, mengapa kita membutuhkannya? Hal ini memerlukan sedikit dari apa yang Anda dapat memanggil "Perpustakaan filsafat."

Jalan memutar "Filsafat" pendek

Pertama, DOM dapat menjadi agak kasar untuk bertengkar untuk pemula; ini adalah alasan yang cukup buruk untuk API.

Jika membangun Perpustakaan hanya tentang menulis kode, itu bukan pekerjaan yang sulit. Tapi karena saya bekerja pada proyek ini, saya menemukan bagian yang sulit adalah memutuskan bagaimana metode tertentu harus bekerja.

Segera, kita akan membangun sebuah metode text yang mengembalikan teks dari elemen yang dipilih. Jika objek Dome membungkus beberapa DOM node (dome.get("li"), misalnya), apa yang harus this kembalikan? Jika Anda melakukan sesuatu yang serupa dalam jQuery ($("li").text()), Anda akan mendapatkan string tunggal dengan teks dari elemen yang dihubungkan bersama-sama. Apakah ini berguna? Saya tidak berpikir begitu, tapi aku tidak yakin apa lebih baik mengembalikan nilai akan menjadi.

Untuk proyek ini, aku akan mengembalikan teks dari elemen sebagai array, kecuali ada hanya satu item dalam array; kemudian kita akan mengembalikan string teks, bukan sebuah array dengan item tunggal. Saya pikir Anda akan paling sering mendapatkan teks dari satu elemen, sehingga kami mengoptimalkan untuk kasus itu. Namun, jika Anda mendapatkan teks lebih dari satu elemen, kami akan mengembalikan sesuatu yang Anda dapat bekerja dengan.

Kembali ke Coding

Jadi, metode mapOne akan cukup menjalankan map, dan kemudian mengembalikan array, atau satu item itu dalam array. Jika Anda masih tidak yakin bagaimana hal ini bermanfaat, tunggu: Anda akan melihat!


Langkah 5: Bekerja dengan Text dan HTML

Selanjutnya, mari kita tambahkan text metode. Seperti jQuery, kita dapat memasukan string dan menetapkan elemen teks, atau tidak menggunakan parameter untuk mendapat teks kembali.

Seperti yang Anda duga, kita perlu memeriksa nilai dalam t text melihat jika kita menetapkan atau mendapatkan. Catatan yang hanya if (teks) tidak bekerja, karena string kosong adalah nilai false.

Jika kami menetapkan, kami akan melakukan forEach atas elemen dan mengatur properti innerText mereka ke text. Jika kita sudah, kita akan kembalikan elemen innerText properti. Catatan kami menggunakan metode mapOne: jika kita bekerja dengan beberapa elemen, ini akan mengembalikan array; Jika tidak, akan hanya string.

Metode html akan melakukan cukup banyak hal yang sama seperti text, kecuali bahwa itu akan menggunakan properti innerHTML, bukan innerText.

Seperti saya katakan: hampir identik.


Langkah 6: Hacking class

Selanjutnya, kami ingin dapat menambah dan menghapus class; Jadi mari kita menulis addClass dan removeClass metode.

Metode addClass kami akan mengambil string atau sebuah array dari nama class. Untuk membuat ini bekerja, kita perlu untuk memeriksa jenis parameter. Jika itu adalah array, kita akan loop atasnya dan membuat sebuah string nama class. Sebaliknya, kita hanya akan menambahkan satu ruang di depan nama class, jadi itu tidak main-main dengan class yang ada pada elemen. Kemudian, kami hanya loop atas elemen dan menambahkan class baru ke properti className.

Cukup sederhana, ya?

Sekarang, bagaimana menghapus class? Untuk tetap sederhana, kami hanya akan mengizinkan menghapus satu class pada satu waktu.

Pada setiap elemen, kita akan membagi el.className ke dalam sebuah array. Kemudian, kita menggunakan white loop untuk mengiris keluar class sampai cs.indexOf(clazz) mengembalikan -1. Kami melakukan ini untuk menutupi kasus tepi mana class yang sama telah ditambahkan ke elemen lebih dari sekali: kita perlu memastikan bahwa itu benar-benar hilang. Setelah kami yakin kita telah memotong setiap instance class, kita bergabung array dengan ruang dan meletakkannya di el.className.


Langkah 7: Memperbaiki Bug di IE

Browser terburuk yang kita hadapi adalah IE8. Di perpustakaan kecil kami, ada hanya satu IE bug yang kita butuhkan untuk berurusan dengan; Untungnya, ini cukup sederhana. IE8 tidak mendukung indexOf metode Array; kami menggunakannya di removeClass, jadi mari kita polyfill ini:

It's pretty sederhana, dan ianya tidak implementasi penuh (tidak mendukung parameter kedua), tapi itu akan bekerja untuk tujuan kita.


Langkah 8: Menyesuaikan atribut

Sekarang, kita ingin fungsi attr. Ini akan mudah, karena hampir identik dengan metode kami text atau html. Seperti metode tersebut, kita akan mampu mendapatkan maupun mengatur atribut: kami akan mengambil nama atribut dan nilai untuk set, dan hanya nama atribut untuk mendapatkan.

Jika val memiliki nilai, kami akan loop melalui elemen dan menetapkan atribut dipilih dengan nilai, menggunakan elemen setAttribute metode. Jika tidak, kita akan menggunakan mapOne untuk mengembalikan bahwa atribut melalui metode getAttribute.


Langkah 9: Menciptakan elemen

Kita harus mampu menciptakan elemen baru, seperti setiap perpustakaan yang baik dapat melakukannya. Tentu saja, ini akan menjadi tidak baik sebagai metode pada contoh Dome, jadi mari kita menempatkan tepat di objek dome.

Seperti yang Anda lihat, kami akan mengambil dua parameter: nama elemen, dan objek atribut. Sebagian besar atribut diterapkan melalui metode attr kami, tapi dua akan mendapatkan perlakuan khusus. Kita akan menggunakan metode addClass untuk properti className, dan metode text untuk properti text. Tentu saja, kita akan perlu untuk membuat elemen dan objek Dome pertama. Berikut adalah semua prakteknya:

Seperti yang Anda lihat, kami menciptakan elemen dan mengirimkannya langsung ke Dome baru objek. Kemudian, kita berurusan dengan atribut. Perhatikan bahwa kita harus menghapus atribut className dan text setelah bekerja dengan mereka. Hal ini membuat mereka dari yang diterapkan sebagai atribut ketika kita loop selama sisa kunci dalam attrs. Tentu saja, kita berakhir dengan mengembalikan objek Dome baru.

Tapi sekarang bahwa kita membuat elemen baru, kita akan ingin memasukkan mereka ke dalam DOM, kan?


Langkah 10: Appending dan Prepending elemen

Selanjutnya, kami akan menulis append dan prepend metode, sekarang, ini adalah fungsi-fungsi yang benar-benar agak sulit untuk menulis, terutama karena beberapa kasus penggunaan. Berikut adalah apa yang kita inginkan untuk dapat melakukan:

Browser terburuk yang kita hadapi adalah IE8.

Penggunaan kasus-kasus adalah sebagai berikut: kita mungkin ingin menambahkan atau ditambahkan

  • satu elemen baru ke satu atau beberapa elemen yang sudah ada.
  • beberapa unsur-unsur baru ke salah satu atau lebih yang ada elemen.
  • salah satu elemen yang ada untuk satu atau beberapa elemen yang sudah ada.
  • beberapa unsur-unsur yang ada untuk satu atau beberapa elemen yang sudah ada.

Catatan: saya menggunakan "new" berarti elemen belum ada di DOM; Ada elemen yang sudah di DOM.

Mari kita melangkah meskipun sekarang:

Kami mengharapkan parameter els menjadi objek Dome. Perpustakaan DOM lengkap menerima hal ini sebagai node atau nodelist, tapi kita tidak akan melakukannya. Kita harus loop atas setiap elemen kami, dan kemudian di dalam itu, kita loop atas setiap elemen yang kami ingin menambahkan.

Jika kita sedang menambahkan els ke lebih dari satu elemen, kita perlu untuk mengkloning mereka. Namun, kami tidak ingin untuk mengkloning node pertama kalinya mereka sedang ditambahkan, hanya masa berikutnya. Jadi kita akan melakukan ini:

Bahwa i berasal dari luar forEach loop: itu adalah index dari elemen parent saat ini. Jika kita tidak menambahkan ke elemen parent pertama, kita akan clone node. Dengan cara ini, sebenarnya node akan pergi di simpul index pertama, dan setiap parent akan mendapatkan salinan. Ini bekerja dengan baik, karena obyek Dome yang disahkan pada sebagai argumen hanya akan memiliki node asli (uncloned). Jadi, jika kita hanya menambahkan satu elemen untuk satu elemen, semua node yang terlibat akan menjadi bagian dari mereka masing-masing objek Dome.

Akhirnya, kami akan benar-benar menambahkan elemen:

Jadi, secara keseluruhan, ini adalah apa yang kami miliki:

prepend metode

Kami ingin untuk mencakup kasus yang sama untuk prepend metode, jadi metode ini cukup sangat mirip:

perbedaannya ketika mengawali adalah bahwa jika Anda secara berurutan menambah daftar elemen elemen lain, mereka akan berakhir dalam urutan terbalik. Karena kita tidak bisa forEach mundur, aku pergi melalui loop mundur dengan for loop. Sekali lagi, kita akan clone node jika ini bukan parent pertama kita akan menambahkan ke.


Langkah 11: Menghapus node

Untuk node manipulasi metode kami terakhir, kami ingin agar dapat menghapus node dari DOM. Mudah, sekali

Hanya iterate melalui node dan memanggil metode removeChild pada setiap elemen parentNode. Keindahan di sini (semua berkat DOM) adalah bahwa objek Dome ini akan masih bekerja dengan baik; kita dapat menggunakan metode apapun yang kita inginkan itu, termasuk menambahkan atau mengawali kembali ke DOM. Nice, eh?


Langkah 12: Bekerja dengan Event

Terakhir, tapi jelas tidak sedikit, kita akan menulis beberapa fungsi untuk event handler.

Seperti yang mungkin Anda ketahui, IE8 menggunakan event IE lama, jadi kita harus memeriksa untuk itu. Juga, kami akan melempar DOM 0 event, hanya karena kita bisa.

Check out metode, dan kemudian kita akan membahas ini:

Di sini, kami memiliki IIFE, dan di dalamnya kita melakukan memeriksa fitur. Jika ada document.addEventListener, kita akan menggunakan itu; Jika tidak, kami akan memeriksa document.attachEvent atau jatuh kembali ke DOM 0 event. Perhatikan bagaimana kita sedang mengembalikan fungsi akhir dari IIFE: Itulah apa yang akan berakhir yang diberikan kepada Dome.prototype.on. Ketika melakukan fitur deteksi, itu sangat berguna untuk dapat menetapkan fungsi yang tepat seperti ini, alih-alih memeriksa untuk fitur setiap kali fungsi dijalankan.

Fungsi off, yang unhooks event handler, hampir identik:


Hanya itu

Saya berharap Anda coba perpustakaan kecil kami, dan mungkin bahkan memperpanjang sedikit. Seperti saya sebutkan sebelumnya, aku memilikinya pada Github, bersama dengan suite Jasmine tes untuk kode kita kita tulis di atas. Jangan ragu untuk fork itu, bermain-main, dan mengirim pull request.

saya jelaskan lagi: tujuan tutorial ini tidak menyarankan bahwa Anda harus selalu menulis perpustakaan Anda sendiri.

Ada tim yang berdedikasi orang-orang yang bekerja sama untuk membuat perpustakaan besar, mapan sebaik mungkin. Intinya di sini adalah untuk memberikan mengintip kecil ke dalam apa yang bisa masuk ke dalam sebuah perpustakaan; Saya harap Anda telah mengambil beberapa tips di sini.

Saya sangat merekomendasikan Anda menggali di sekitar dalam beberapa perpustakaan favorit Anda. Anda akan menemukan bahwa mereka tidak begitu samar sebagai Anda mungkin berpikir, dan Anda mungkin akan belajar banyak. Berikut adalah beberapa tempat yang bagus untuk memulai:

Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.