Membangun perpustakaan JavaScript pertama Anda
() translation by (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
danprepend
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)
1 |
window.dome = (function () { |
2 |
function Dome (els) { |
3 |
|
4 |
}
|
5 |
|
6 |
var dome = { |
7 |
get: function (selector) { |
8 |
|
9 |
}
|
10 |
};
|
11 |
|
12 |
return dome; |
13 |
}());
|
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.
1 |
get: function (selector) { |
2 |
var els; |
3 |
if (typeof selector === "string") { |
4 |
els = document.querySelectorAll(selector); |
5 |
} else if (selector.length) { |
6 |
els = selector; |
7 |
} else { |
8 |
els = [selector]; |
9 |
}
|
10 |
return new Dome(els); |
11 |
}
|
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:
1 |
function Dome (els) { |
2 |
for(var i = 0; i < els.length; i++ ) { |
3 |
this[i] = els[i]; |
4 |
}
|
5 |
this.length = els.length; |
6 |
}
|
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 Dom
e 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
:
1 |
Dome.prototype.map = function (callback) { |
2 |
var results = [], i = 0; |
3 |
for ( ; i < this.length; i++) { |
4 |
results.push(callback.call(this, this[i], i)); |
5 |
}
|
6 |
return results; |
7 |
};
|
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:
1 |
callback.call(this, this[i], i)); |
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:
1 |
Dome.prototype.forEach(callback) { |
2 |
this.map(callback); |
3 |
return this; |
4 |
};
|
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:
1 |
Dome.prototype.someMethod1 = function (callback) { |
2 |
this.forEach(callback); |
3 |
return this; |
4 |
};
|
5 |
|
6 |
Dome.prototype.someMethod2 = function (callback) { |
7 |
return this.forEach(callback); |
8 |
};
|
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!
1 |
Dome.prototype.mapOne = function (callback) { |
2 |
var m = this.map(callback); |
3 |
return m.length > 1 ? m : m[0]; |
4 |
};
|
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.
1 |
Dome.prototype.text = function (text) { |
2 |
if (typeof text !== "undefined") { |
3 |
return this.forEach(function (el) { |
4 |
el.innerText = text; |
5 |
});
|
6 |
} else { |
7 |
return this.mapOne(function (el) { |
8 |
return el.innerText; |
9 |
});
|
10 |
}
|
11 |
};
|
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
.
1 |
Dome.prototype.html = function (html) { |
2 |
if (typeof html !== "undefined") { |
3 |
this.forEach(function (el) { |
4 |
el.innerHTML = html; |
5 |
});
|
6 |
return this; |
7 |
} else { |
8 |
return this.mapOne(function (el) { |
9 |
return el.innerHTML; |
10 |
});
|
11 |
}
|
12 |
};
|
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
.
1 |
Dome.prototype.addClass = function (classes) { |
2 |
var className = ""; |
3 |
if (typeof classes !== "string") { |
4 |
for (var i = 0; i < classes.length; i++) { |
5 |
className += " " + classes[i]; |
6 |
}
|
7 |
} else { |
8 |
className = " " + classes; |
9 |
}
|
10 |
return this.forEach(function (el) { |
11 |
el.className += className; |
12 |
});
|
13 |
};
|
Cukup sederhana, ya?
Sekarang, bagaimana menghapus class? Untuk tetap sederhana, kami hanya akan mengizinkan menghapus satu class pada satu waktu.
1 |
Dome.prototype.removeClass = function (clazz) { |
2 |
return this.forEach(function (el) { |
3 |
var cs = el.className.split(" "), i; |
4 |
|
5 |
while ( (i = cs.indexOf(clazz)) > -1) { |
6 |
cs = cs.slice(0, i).concat(cs.slice(++i)); |
7 |
}
|
8 |
el.className = cs.join(" "); |
9 |
});
|
10 |
};
|
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:
1 |
if (typeof Array.prototype.indexOf !== "function") { |
2 |
Array.prototype.indexOf = function (item) { |
3 |
for(var i = 0; i < this.length; i++) { |
4 |
if (this[i] === item) { |
5 |
return i; |
6 |
}
|
7 |
}
|
8 |
return -1; |
9 |
};
|
10 |
}
|
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.
1 |
Dome.prototype.attr = function (attr, val) { |
2 |
if (typeof val !== "undefined") { |
3 |
return this.forEach(function(el) { |
4 |
el.setAttribute(attr, val); |
5 |
});
|
6 |
} else { |
7 |
return this.mapOne(function (el) { |
8 |
return el.getAttribute(attr); |
9 |
});
|
10 |
}
|
11 |
};
|
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
.
1 |
var dome = { |
2 |
// get method here
|
3 |
create: function (tagName, attrs) { |
4 |
|
5 |
}
|
6 |
};
|
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:
1 |
create: function (tagName, attrs) { |
2 |
var el = new Dome([document.createElement(tagName)]); |
3 |
if (attrs) { |
4 |
if (attrs.className) { |
5 |
el.addClass(attrs.className); |
6 |
delete attrs.className; |
7 |
}
|
8 |
if (attrs.text) { |
9 |
el.text(attrs.text); |
10 |
delete attrs.text; |
11 |
}
|
12 |
for (var key in attrs) { |
13 |
if (attrs.hasOwnProperty(key)) { |
14 |
el.attr(key, attrs[key]); |
15 |
}
|
16 |
}
|
17 |
}
|
18 |
return el; |
19 |
}
|
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:
1 |
dome1.append(dome2); |
2 |
dome1.prepend(dome2); |
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:
1 |
Dome.prototype.append = function (els) { |
2 |
this.forEach(function (parEl, i) { |
3 |
els.forEach(function (childEl) { |
4 |
|
5 |
});
|
6 |
});
|
7 |
};
|
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:
1 |
if (i > 0) { |
2 |
childEl = childEl.cloneNode(true); |
3 |
}
|
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:
1 |
parEl.appendChild(childEl); |
Jadi, secara keseluruhan, ini adalah apa yang kami miliki:
1 |
Dome.prototype.append = function (els) { |
2 |
return this.forEach(function (parEl, i) { |
3 |
els.forEach(function (childEl) { |
4 |
if (i > 0) { |
5 |
childEl = childEl.cloneNode(true); |
6 |
}
|
7 |
parEl.appendChild(childEl); |
8 |
});
|
9 |
});
|
10 |
};
|
prepend
metode
Kami ingin untuk mencakup kasus yang sama untuk prepend
metode, jadi metode ini cukup sangat mirip:
1 |
Dome.prototype.prepend = function (els) { |
2 |
return this.forEach(function (parEl, i) { |
3 |
for (var j = els.length -1; j > -1; j--) { |
4 |
childEl = (i > 0) ? els[j].cloneNode(true) : els[j]; |
5 |
parEl.insertBefore(childEl, parEl.firstChild); |
6 |
}
|
7 |
});
|
8 |
};
|
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
1 |
Dome.prototype.remove = function () { |
2 |
return this.forEach(function (el) { |
3 |
return el.parentNode.removeChild(el); |
4 |
});
|
5 |
};
|
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:
1 |
Dome.prototype.on = (function () { |
2 |
if (document.addEventListener) { |
3 |
return function (evt, fn) { |
4 |
return this.forEach(function (el) { |
5 |
el.addEventListener(evt, fn, false); |
6 |
});
|
7 |
};
|
8 |
} else if (document.attachEvent) { |
9 |
return function (evt, fn) { |
10 |
return this.forEach(function (el) { |
11 |
el.attachEvent("on" + evt, fn); |
12 |
});
|
13 |
};
|
14 |
} else { |
15 |
return function (evt, fn) { |
16 |
return this.forEach(function (el) { |
17 |
el["on" + evt] = fn; |
18 |
});
|
19 |
};
|
20 |
}
|
21 |
}());
|
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:
1 |
Dome.prototype.off = (function () { |
2 |
if (document.removeEventListener) { |
3 |
return function (evt, fn) { |
4 |
return this.forEach(function (el) { |
5 |
el.removeEventListener(evt, fn, false); |
6 |
});
|
7 |
};
|
8 |
} else if (document.detachEvent) { |
9 |
return function (evt, fn) { |
10 |
return this.forEach(function (el) { |
11 |
el.detachEvent("on" + evt, fn); |
12 |
});
|
13 |
};
|
14 |
} else { |
15 |
return function (evt, fn) { |
16 |
return this.forEach(function (el) { |
17 |
el["on" + evt] = null; |
18 |
});
|
19 |
};
|
20 |
}
|
21 |
}());
|
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:
- 10 hal yang saya pelajari dari jQuery sumber (oleh Paul Irish)
- 11 lebih banyak hal yang saya pelajari dari jQuery sumber (juga oleh Paul Irish)
- Di bawah jQuery's Bonnet (oleh James Padolsey)
- Backbone.js: Hacker panduan, Bagian 1, Bagian 2, Bagian 3, Bagian 4
- Tahu Perpustakaan bagus yang lain? Mari kita lihat di komentar!