14 Trik jQuery yang Berguna, Catatan, dan Praktik Terbaik
Indonesian (Bahasa Indonesia) translation by ⚡ Rova Rindrata (you can also view the original English article)
Jika ada satu hal buruk tentang jQuery, itu adalah bahwa tingkat entri yang sangat luar biasa rendah, sehingga cenderung menarik orang-orang yang tidak memiliki sedikitpun pengetahuan JavaScript. Nah, di satu sisi, ini fantastis. Namun, di sisi lain, ini juga menghasilkan sedikit kode yang benar-benar menjijikkan (beberapa di antaranya yang saya tulis sendiri!).
Tapi tidak apa-apa; kode yang amat sangat buruk yang bahkan membuat nenek Anda terkesiap adalah sebuah ritual perjalanan. Kuncinya adalah mendaki bukit, dan itulah yang akan kita bahas di tutorial hari ini.
1. Metode Mengembalikan Objek jQuery
Penting untuk diingat bahwa kebanyakan metode akan mengembalikan objek jQuery. Ini sangat membantu, dan memungkinkan fungsi berantai yang sering kita gunakan.
$someDiv .attr('class', 'someClass') .hide() .html('new stuff');
Mengetahui bahwa objek jQuery selalu dikembalikan, kita bisa menggunakannya untuk menghapus kode yang berlebihan. Misalnya, perhatikan kode berikut ini:
var someDiv = $('#someDiv'); someDiv.hide();
Alasan mengapa kita "cache" lokasi dari elemen
someDiv
adalah untuk membatasi berapa kali kita harus melewati DOM untuk elemen ini untuk sekali.
Kode di atas baik-baik saja; namun, Anda bisa dengan mudah menggabungkan dua baris menjadi satu, sementara mencapai hasil yang sama.
var someDiv = $('#someDiv').hide();
Dengan cara ini, kita masih menyembunyikan elemen someDiv
, tapi caranya juga, seperti yang kita pelajari, mengembalikan objek jQuery -- yang kemudian dirujuk melalui variabel someDiv
.
2. Penyeleksi Find
Selama penyeleksi Anda tidak terlalu buruk, jQuery melakukan pekerjaan yang fantastis untuk mengoptimalkannya sebaik mungkin, dan Anda biasanya tidak perlu terlalu memikirkannya. Namun, dengan mengatakan bahwa, ada beberapa perbaikan yang dapat Anda lakukan yang akan sedikit memperbaiki kinerja skrip Anda.
Salah satu solusi tersebut adalah dengan menggunakan metode find()
, bila memungkinkan. Kuncinya adalah menyimpang dari memaksa jQuery untuk menggunakan mesin Sizzle-nya, jika itu tidak perlu. Tentu, akan ada saat dimana hal ini tidak memungkinkan -- dan tidak apa-apa; tapi, jika Anda tidak memerlukan tambahan apapun, jangan mencarinya.
// Fine in modern browsers, though Sizzle does begin "running" $('#someDiv p.someClass').hide(); // Better for all browsers, and Sizzle never inits. $('#someDiv').find('p.someClass').hide();
Browser modern terbaru memiliki dukungan untuk
QuerySelectorAll
, yang memungkinkan Anda melewati penyeleksi seperti CSS, tanpa memerlukan jQuery. jQuery sendiri memeriksa fungsi ini juga.
Namun, browser lawas, yakni IE6/IE7, bisa dimengerti tidak memberikan dukungan. Apa artinya ini adalah bahwa penyeleksi yang lebih rumit ini memicu mesin Sizzle jQuery sepenuhnya, yang meski brilian, datang bersamaan dengan tambahan yang sedikit lebih banyak.
Sizzle adalah kode brilian yang mungkin tidak pernah saya mengerti. Namun, dalam sebuah kalimat, pertama-tama mengambil penyeleksi Anda dan mengubahnya menjadi "array" yang terdiri dari setiap komponen penyeleksi Anda.
// Rough idea of how it works ['#someDiv, 'p'];
Kemudian, dari kanan ke kiri, mulai menguraikan setiap item dengan regular expressions. Apa ini juga berarti bahwa bagian dari penyeleksi Anda harus sespesifik mungkin -- misalnya, id
atau nama tag.
Intinya, bila memungkinkan:
- Jaga agar penyeleksi Anda tetap sederhana
- Manfaatkan metode
find()
. Dengan cara ini, daripada menggunakan Sizzle, kita dapat terus menggunakan fungsi asli browser. - Saat menggunakan Sizzle, optimalkan bagian dari penyeleksi sebanyak mungkin.
Konteks Sebaliknya?
Juga memungkinkan untuk menambahkan konteks ke penyeleksi Anda, seperti:
$('.someElements', '#someContainer').hide();
Kode ini mengarahkan jQuery untuk membungkus kumpulan semua elemen dengan kelas someElements
-- yang merupakan turunan dari someContainer
-- di dalam jQuery. Menggunakan konteks adalah cara yang sangat membantu untuk membatasi penjelajahan DOM, meskipun, di balik layar, jQuery menggunakan metode find
.
$('#someContainer') .find('.someElements') .hide();
Bukti
// HANDLE: $(expr, context) // (which is just equivalent to: $(context).find(expr) } else { return jQuery( context ).find( selector ); }
3. Jangan Menyalahgunakan $(this)
Tanpa mengetahui tentang berbagai properti dan fungsi DOM, mudah untuk menyalahgunakan objek jQuery dengan sia-sia. Sebagai contoh:
$('#someAnchor').click(function() { // Bleh alert( $(this).attr('id') ); });
Jika satu-satunya kebutuhan objek jQuery adalah mengakses atribut id
dari tag anchor, ini sangat sia-sia. Lebih baik tetap dengan JavaScript "mentah".
$('#someAnchor').click(function() { alert( this.id ); });
Perlu diketahui bahwa ada tiga atribut yang selalu dapat diakses, melalui jQuery: "src," "href," dan "style." Atribut ini memerlukan penggunaan
getAttribute
di versi IE yang lebih lawas.
Bukti
// jQuery Source var rspecialurl = /href|src|style/; // ... var special = rspecialurl.test( name ); // ... var attr = !jQuery.support.hrefNormalized && notxml && special ? // Some attributes require a special call on IE elem.getAttribute( name, 2 ) : elem.getAttribute( name );
Beberapa Objek jQuery
Yang lebih buruk lagi adalah proses kueri DOM berulang kali dan membuat beberapa objek jQuery.
$('#elem').hide(); $('#elem').html('bla'); $('#elem').otherStuff();
Mudah-mudahan, Anda sudah tahu betapa tidak efisiennya kode ini. Jika tidak, tidak apa-apa; kita semua sedang belajar. Jawabannya adalah menerapkan chaining, atau melakukan "cache" dari lokasi #elem
.
// This works better $('#elem') .hide() .html('bla') .otherStuff(); // Or this, if you prefer for some reason. var elem = $('#elem'); elem.hide(); elem.html('bla'); elem.otherStuff();
4. Metode Singkat Ready
jQuery
Memperhatikan saat dokumen siap dimanipulasi bisa ditebak dengan mudah menggunakan jQuery.
$(document).ready(function() { // let's get up in heeya });
Meskipun, sangat mungkin Anda bisa menemukan fungsi pembungkus yang berbeda dan lebih membingungkan.
$(function() { // let's get up in heeya });
Meskipun yang terakhir ini agak kurang mudah dibaca, kedua cuplikan di atas adalah identik. Tidak percaya pada saya? Cukup periksa sumber jQuery.
// HANDLE: $(function) // Shortcut for document ready if ( jQuery.isFunction( selector ) ) { return rootjQuery.ready( selector ); }
rootjQuery
hanyalah referensi ke root jQuery(document)
. Ketika Anda melewatkan sebuah penyeleksi ke fungsi jQuery, itu akan menentukan jenis penyeleksi yang Anda lewatkan: string, tag, id, fungsi, dll. Jika sebuah fungsi dilewatkan, jQuery kemudian akan memanggil metode ready()
, dan melewatkan fungsi anonim Anda sebagai penyeleksi.
5. Jaga agar Kode Anda tetap Aman
Jika mengembangkan kode untuk distribusi, selalu penting untuk mengkompensasi kemungkinan benturan nama. Apa yang akan terjadi jika beberapa skrip, yang diimpor setelah milik Anda, juga memiliki fungsi $
? Hal-hal buruk!
Jawabannya adalah memanggil noConflict()
dari jQuery, atau menyimpan kode Anda dalam fungsi anonim yang memanggil dirinya sendiri, dan kemudian melewatkan jQuery untuknya.
Metode 1: NoConflict
var j = jQuery.noConflict(); // Now, instead of $, we use j. j('#someDiv').hide(); // The line below will reference some other library's $ function. $('someDiv').style.display = 'none';
Berhati-hatilah dengan metode ini, dan cobalah untuk tidak menggunakannya saat mendistribusikan kode Anda. Ini benar-benar akan membingungkan pengguna skrip Anda! :)
Metode 2: Melewatkan jQuery
(function($) { // Within this function, $ will always refer to jQuery })(jQuery);
Tanda kurung terakhir di bagian bawah memanggil fungsi secara otomatis - function(){}()
. Namun, ketika kita memanggil fungsinya, kita juga melewatkan jQuery, yang kemudian diwakili oleh $
.
Metode 3: Melewatkan $ Melalui Metode Ready
jQuery(document).ready(function($) { // $ refers to jQuery }); // $ is either undefined, or refers to some other library's function.
6. Jadilah Pintar
Ingat - jQuery hanyalah JavaScript. Jangan berasumsi bahwa ia memiliki kemampuan untuk mengkompensasi pengkodean buruk Anda. :)
Ini berarti, sama seperti kita harus mengoptimalkan hal-hal seperti pernyataan for
JavaScript, hal yang sama berlaku untuk metode each
jQuery. Dan kenapa tidak? Ini hanyalah metode pembantu, yang kemudian menciptakan sebuah pernyataan for
di balik layar.
// jQuery's each method source each: function( object, callback, args ) { var name, i = 0, length = object.length, isObj = length === undefined || jQuery.isFunction(object); if ( args ) { if ( isObj ) { for ( name in object ) { if ( callback.apply( object[ name ], args ) === false ) { break; } } } else { for ( ; i < length; ) { if ( callback.apply( object[ i++ ], args ) === false ) { break; } } } // A special, fast, case for the most common use of each } else { if ( isObj ) { for ( name in object ) { if ( callback.call( object[ name ], name, object[ name ] ) === false ) { break; } } } else { for ( var value = object[0]; i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {} } } return object; }
Mengerikan
someDivs.each(function() { $('#anotherDiv')[0].innerHTML += $(this).text(); });
- Mencari
anotherDiv
untuk iterasi each - Meraih properti innerHTML dua kali
- Membuat objek jQuery baru, semuanya untuk mengakses teks dari elemen.
Lebih baik
var someDivs = $('#container').find('.someDivs'), contents = []; someDivs.each(function() { contents.push( this.innerHTML ); }); $('#anotherDiv').html( contents.join('') );
Dengan cara ini, dalam metode each
(for), satu-satunya tugas yang kita lakukan adalah menambahkan kunci baru ke array... sebagai lawan untuk kueri DOM, meraih properti innerHTML
dari elemen dua kali, dll.
Tip ini lebih berbasis JavaScript pada umumnya, bukan spesifik jQuery. Intinya adalah mengingat bahwa jQuery tidak mengkompensasi pengkodean yang buruk.
Fragmen Dokumen
Sementara kita melakukannya, pilihan lain untuk situasi semacam ini adalah dengan menggunakan fragmen dokumen.
var someUls = $('#container').find('.someUls'), frag = document.createDocumentFragment(), li; someUls.each(function() { li = document.createElement('li'); li.appendChild( document.createTextNode(this.innerHTML) ); frag.appendChild(li); }); $('#anotherUl')[0].appendChild( frag );
Kuncinya di sini adalah bahwa ada banyak cara untuk menyelesaikan tugas sederhana seperti ini, dan masing-masing memiliki keuntungan kinerja sendiri dari browser ke browser. Semakin Anda tetap pada jQuery dan belajar JavaScript, Anda mungkin juga menganggap bahwa Anda merujuk pada properti dan metode asli JavaScript lebih sering. Dan, kalau begitu, itu fantastis!
jQuery memberikan tingkat abstraksi yang luar biasa yang harus Anda manfaatkan, tapi ini tidak berarti Anda terpaksa menggunakan metodenya. Sebagai contoh, dalam contoh fragmen di atas, kita menggunakan metode each
jQuery. Jika Anda lebih suka menggunakan for
atau pernyataan while
sebagai gantinya, tidak apa-apa juga!
Dengan semua itu, ingatlah bahwa tim jQuery telah banyak mengoptimalkan perpustakaan ini. Perdebatan tentang
each()
jQuery vs pernyataanfor
yang asli adalah konyol dan sepele. Jika Anda menggunakan jQuery dalam proyek Anda, menghemat waktu dan gunakan metode pembantu mereka. Itulah tujuan mereka! :)
7. Metode AJAX
Jika Anda baru saja mulai menggali jQuery, berbagai metode AJAX yang tersedia bagi kita mungkin akan menjadi sedikit menakutkan; meskipun tidak perlu. Sebenarnya, kebanyakan dari mereka hanyalah metode pembantu, yang rutenya langsung ke $.ajax
.
- get
- getJSON
- post
- ajax
Sebagai contoh, mari kita tinjau getJSON
, yang memungkinkan kita mengambil JSON.
$.getJSON('path/to/json', function(results) { // callback // results contains the returned data object });
Di balik layar, metode ini pertama kali memanggil $.get
.
getJSON: function( url, data, callback ) { return jQuery.get(url, data, callback, "json"); }
$.get
kemudian mengkompilasi data yang dilalui, dan, sekali lagi, memanggil metode "master" (semacam) $.ajax
.
get: function( url, data, callback, type ) { // shift arguments if data argument was omited if ( jQuery.isFunction( data ) ) { type = type || callback; callback = data; data = null; } return jQuery.ajax({ type: "GET", url: url, data: data, success: callback, dataType: type }); }
Akhirnya, $.ajax
melakukan sejumlah besar pekerjaan untuk memungkinkan kita berhasil membuat permintaan asinkron di semua browser!
Apa ini berarti Anda bisa menggunakan metode
$.ajax
secara langsung dan eksklusif untuk semua permintaan AJAX Anda. Metode lainnya hanyalah metode penolong yang akhirnya melakukan hal ini juga. Jadi, kalau Anda mau, potong orang yang berada di tengahnya. Ini bukanlah masalah yang signifikan.
Hanya hal yang bagus
$.getJSON('path/to/json', function(results) { // callback // results contains the returned data object });
Secara Mikroskopis Lebih Efisien
$.ajax({ type: 'GET', url : 'path/to/json', data : yourData, dataType : 'json', success : function( results ) { console.log('success'); }) });
8. Mengakses Properti dan Metode Asli
Demikian, Anda telah mempelajari sedikit JavaScript, dan telah mengetahui bahwa, misalnya, pada tag anchor, Anda dapat langsung mengakses nilai atributnya:
var anchor = document.getElementById('someAnchor'); //anchor.id // anchor.href // anchor.title // .etc
Satu-satunya masalah adalah bahwa ini sepertinya tidak bekerja saat Anda merujuk elemen DOM dengan jQuery, bukan? Tentu saja tidak.
Tidak akan bekerja
// Fails var id = $('#someAnchor').id;
Jadi, jika Anda perlu mengakses atribut href
(atau properti atau metode asli lainnya dalam hal ini), Anda memiliki beberapa pilihan.
// OPTION 1 - Use jQuery var id = $('#someAnchor').attr('id'); // OPTION 2 - Access the DOM element var id = $('#someAnchor')[0].id; // OPTION 3 - Use jQuery's get method var id = $('#someAnchor').get(0).id; // OPTION 3b - Don't pass an index to get anchorsArray = $('.someAnchors').get(); var thirdId = anchorsArray[2].id;
Metode
get
sangat membantu, karena dapat menerjemahkan koleksi jQuery Anda ke dalam sebuah array.
9. Mendeteksi Permintaan AJAX dengan PHP
Tentu, untuk sebagian besar proyek kita, kita tidak hanya mengandalkan JavaScript untuk hal-hal seperti validasi, atau permintaan AJAX. Apa yang terjadi saat JavaScript dimatikan? Untuk alasan ini, teknik yang umum adalah mendeteksi apakah permintaan AJAX telah dibuat dengan bahasa sisi server pilihan Anda.
jQuery membuat hal ini sangat sederhana, dengan menetapkan header dari dalam metode $.ajax
.
// Set header so the called script knows that it's an XMLHttpRequest // Only send the header if it's not a remote XHR if ( !remote ) { xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); }
Dengan rangkaian header ini, sekarang kita bisa menggunakan PHP (atau bahasa lainnya) untuk memeriksa header ini, dan melanjutkan sesuai dengannya. Untuk ini, kita memeriksa nilai $_SERVER['HTTP_X_REQUESTED_WITH']
.
Pembungkus
function isXhr() { return $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest'; }
10. jQuery dan $
Pernahkah bertanya-tanya mengapa/bagaimana Anda bisa menggunakan jQuery
dan $
secara bergantian? Untuk menemukan jawaban Anda, lihat sumber jQuery, dan gulir ke bagian paling bawah. Di sana, Anda akan melihat:
window.jQuery = window.$ = jQuery;
Keseluruhan skrip jQuery, tentu saja, dibungkus dalam fungsi self-executing, yang memungkinkan skirp membatasi jumlah variabel global sebanyak mungkin. Apa ini juga berarti, bagaimanapun juga, adalah bahwa objek jQuery tidak tersedia di luar fungsi anonim pembungkus.
Untuk memperbaiki ini, jQuery terkena objek window
global, dan, dalam prosesnya, alias - $
- juga dibuat.
11. Pemuatan jQuery dengan Kondisional
HTML5 Boilerplate menawarkan satu baris bagus yang akan memuat salinan jQuery lokal jika, untuk beberapa alasan aneh, CDN pilihan Anda sedang bermasalah.
<!-- Grab Google CDN jQuery. fall back to local if necessary --> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> <script>!window.jQuery && document.write('<script src="js/jquery-1.4.2.min.js"><\/script>')</script>
Untuk "mengutarakan" kode di atas: jika window.jQuery tidak terdefinisi, pasti ada masalah saat mengunduh skrip dari CDN. Dalam hal ini, lanjutkan ke sisi kanan dari operator &&
, dan masukkan skrip yang terhubung ke jQuery versi lokal.
12. Filter jQuery
Anggota Premium: Unduh Video ini (Harus login)
Berlangganan ke halaman YouTube kami untuk menonton semua video tutorial!
<script> $('p:first').data('info', 'value'); // populates $'s data object to have something to work with $.extend( jQuery.expr[":"], { block: function(elem) { return $(elem).css("display") === "block"; }, hasData : function(elem) { return !$.isEmptyObject( $(elem).data() ); } } ); $("p:hasData").text("has data"); // grabs paras that have data attached $("p:block").text("are block level"); // grabs only paragraphs that have a display of "block" </script>
Catatan:
jQuery.expr[':']
hanyalah sebuah alias untukjQuery.expr.filters
.
13. Fungsi Hover Tunggal
Pada jQuery 1.4, sekarang kita hanya bisa melewatkan satu fungsi ke metode hover
. Sebelumnya, diperlukan metode in dan out.
Sebelum
$('#someElement').hover(function() { // mouseover }, function() { // mouseout });
Sekarang
$('#someElement').hover(function() { // the toggle() method can be used here, if applicable });
Perhatikan bahwa ini bukan kesepakatan lama vs baru. Sering kali, Anda masih perlu melewatkan dua fungsi untuk hover
, dan itu bisa diterima dengan sempurna. Namun, jika Anda hanya perlu toggle beberapa elemen (atau semacamnya), melewatkan satu fungsi anonim akan menghemat beberapa karakter atau lebih!
14. Melewatkan Objek Atribut
Pada jQuery 1.4, kita sekarang bisa melewatkan sebuah objek sebagai parameter kedua dari fungsi jQuery. Ini sangat membantu bila kita perlu memasukkan elemen baru ke DOM. Sebagai contoh:
Sebelum
$('<a />') .attr({ id : 'someId', className : 'someClass', href : 'somePath.html' });
Sesudah
$('</a>', { id : 'someId', className : 'someClass', href : 'somePath.html' });
Ini tidak hanya menghemat beberapa karakter, tapi juga membuat kode lebih bersih. Selain atribut elemen, kita bahkan bisa melewatkan atribut dan aktivitas jQuery tertentu, seperti click
atau text
.
Terima kasih telah membaca!