14个有用的jQuery技巧,笔记 和最佳实践
2011-12-19 12:43
645 查看
这篇文章来自http://net.tutsplus.com/tutorials/javascript-ajax/14-helpful-jquery-tricks-notes-and-best-practices/,是我在css88网站看到的,贴过来备用。本想翻译的,想想还是看英文比较好,原汁原味。
14 Helpful jQuery Tricks, Notes, and Best Practices
If there is one bad thing about jQuery, it’s that the entry level is so amazingly low, that it tends to attract those who haven’t an ounce of JavaScript knowledge. Now, on one hand, this is fantastic. However, on the flip side, it also results in a smattering of, quite frankly, disgustingly bad code (some of which I wrote myself!).
But that’s okay; frighteningly poor code that would even make your grandmother gasp is a rite of passage. The key is to climb over the hill, and that’s what we’ll discuss in today’s tutorial.
view plaincopy to clipboardprint?
$someDiv
.attr('class', 'someClass')
.hide()
.html('new stuff');
Knowing that the jQuery object is always returned, we can use this to remove superfluous code at times. For example, consider the following code:
view plaincopy to clipboardprint?
var someDiv = $('#someDiv');
someDiv.hide();
view plaincopy to clipboardprint?
var someDiv = $('#someDiv').hide();
This way, we still hide the
One such solution is to use the
view plaincopy to clipboardprint?
// 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();
// Rough idea of how it works
['#someDiv, 'p'];
It then, from right to left, begins deciphering each item with regular expressions. What this also means is that the right-most part of your selector should be as specific as possible — for instance, an
Bottom line, when possible:
Keep your selectors simple
Utilize the
When using Sizzle, optimize the right-most part of your selector as much as possible.
Context Instead? It’s also possible to add a context to your selectors, such as:
view plaincopy to clipboardprint?
$('.someElements', '#someContainer').hide();
This code directs jQuery to wrap a collection of all the elements with a class of
view plaincopy to clipboardprint?
$('#someContainer')
.find('.someElements')
.hide();
Proof view plaincopy to clipboardprint?
// HANDLE: $(expr, context)
// (which is just equivalent to: $(context).find(expr)
} else {
return jQuery( context ).find( selector );
}
3. Don’t Abuse
Without knowing about the various DOM properties and functions, it can be easy to abuse the jQuery object needlessly. For instance:
view plaincopy to clipboardprint?
$('#someAnchor').click(function() {
// Bleh
alert( $(this).attr('id') );
});
If our only need of the jQuery object is to access the anchor tag’s
view plaincopy to clipboardprint?
$('#someAnchor').click(function() {
alert( this.id );
});
// 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 );
Multiple jQuery Objects Even worse is the process of repeatedly querying the DOM and creating multiple jQuery objects.
view plaincopy to clipboardprint?
$('#elem').hide();
$('#elem').html('bla');
$('#elem').otherStuff();
Hopefully, you’re already aware of how inefficient this code is. If not, that’s okay; we’re all learning. The answer is to either implement chaining, or to “cache” the location of
view plaincopy to clipboardprint?
// 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. jQuery’s Shorthand
Listening for when the document is ready to be manipulated is laughably simple with jQuery.
view plaincopy to clipboardprint?
$(document).ready(function() {
// let's get up in heeya
});
Though, it’s very possible that you might have come across a different, more confusing wrapping function.
view plaincopy to clipboardprint?
$(function() {
// let's get up in heeya
});
Though the latter is somewhat less readable, the two snippets above are identical. Don’t believe me? Just check the jQuery source.
view plaincopy to clipboardprint?
// HANDLE: $(function)
// Shortcut for document ready
if ( jQuery.isFunction( selector ) ) {
return rootjQuery.ready( selector );
}
The answer is to either call jQuery’s
Method 1: NoConflict view plaincopy to clipboardprint?
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';
Be careful with this method, and try not to use it when distributing your code. It would really confuse the user of your script! :)
Method 2: Passing jQuery view plaincopy to clipboardprint?
(function($) {
// Within this function, $ will always refer to jQuery
})(jQuery);
The final parens at the bottom call the function automatically –
Method 3: Passing $ via the
jQuery(document).ready(function($) {
// $ refers to jQuery
});
// $ is either undefined, or refers to some other library's function.
This means that, just as we must optimize things such as JavaScript
view plaincopy to clipboardprint?
// 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;
}
Awful view plaincopy to clipboardprint?
someDivs.each(function() {
$('#anotherDiv')[0].innerHTML += $(this).text();
});
Searches for
Grabs the innerHTML property twice
Creates a new jQuery object, all to access the text of the element.
Better view plaincopy to clipboardprint?
var someDivs = $('#container').find('.someDivs'),
contents = [];
someDivs.each(function() {
contents.push( this.innerHTML );
});
$('#anotherDiv').html( contents.join('') );
This way, within the
This tip is more JavaScript-based in general, rather than jQuery specific. The point is to remember that jQuery doesn't compensate for poor coding.
Document Fragments While we're at it, another option for these sorts of situations is to use document fragments.
view plaincopy to clipboardprint?
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 );
The key here is that there are multiple ways to accomplish simple tasks like this, and each have their own performance benefits from browser to browser. The more you stick with jQuery and learn JavaScript, you also might find that you refer to JavaScript's native properties and methods more often. And, if so, that's fantastic!
jQuery provides an amazing level of abstraction that you should take advantage of, but this doesn't mean that you're forced into using its methods. For example, in the fragment example above, we use jQuery's
get
getJSON
post
ajax
As an example, let's review
view plaincopy to clipboardprint?
$.getJSON('path/to/json', function(results) {
// callback
// results contains the returned data object
});
Behind the scenes, this method first calls
view plaincopy to clipboardprint?
getJSON: function( url, data, callback ) {
return jQuery.get(url, data, callback, "json");
}
view plaincopy to clipboardprint?
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
});
}
Finally,
$.getJSON('path/to/json', function(results) {
// callback
// results contains the returned data object
});
Microscopically More Efficient view plaincopy to clipboardprint?
$.ajax({
type: 'GET',
url : 'path/to/json',
data : yourData,
dataType : 'json',
success : function( results ) {
console.log('success');
})
});
view plaincopy to clipboardprint?
var anchor = document.getElementById('someAnchor');
//anchor.id
// anchor.href
// anchor.title
// .etc
The only problem is that this doesn't seem to work when you reference the DOM elements with jQuery, right? Well of course not.
Won't Work view plaincopy to clipboardprint?
// Fails
var id = $('#someAnchor').id;
So, should you need to access the
view plaincopy to clipboardprint?
// 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;
jQuery makes this ridiculously simple, by setting a header from within the
view plaincopy to clipboardprint?
// 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");
}
With this header set, we can now use PHP (or any other language) to check for this header, and proceed accordingly. For this, we check the value of
Wrapper view plaincopy to clipboardprint?
function isXhr() {
return $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest';
}
window.jQuery = window.$ = jQuery;
The entire jQuery script is, of course, wrapped within a self-executing function, which allows the script to limit the number of global variables as much as possible. What this also means, though, is that the jQuery object is not available outside of the wrapping anonymous function.
To fix this, jQuery is exposed to the global
view plaincopy to clipboardprint?
<!-- 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>
To "phrase" the code above: if window.jQuery is undefined, there must have been a problem downloading the script from the CDN. In that case, proceed to the right side of the
Subscribe to our YouTube page to watch all of the video tutorials!
view plaincopy to clipboardprint?
<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>
Before view plaincopy to clipboardprint?
$('#someElement').hover(function() {
// mouseover
}, function() {
// mouseout
});
Now view plaincopy to clipboardprint?
$('#someElement').hover(function() {
// the toggle() method can be used here, if applicable
});
Note that this isn't an old vs. new deal. Many times, you'll still need to pass two functions to
Before view plaincopy to clipboardprint?
$('<a />')
.attr({
id : 'someId',
className : 'someClass',
href : 'somePath.html'
});
After view plaincopy to clipboardprint?
$('</a>', {
id : 'someId',
className : 'someClass',
href : 'somePath.html'
});
Not only does this save a few characters, but it also makes for cleaner code. In addition to element attributes, we can even pass jQuery specific attributes and events, like
14 Helpful jQuery Tricks, Notes, and Best Practices
If there is one bad thing about jQuery, it’s that the entry level is so amazingly low, that it tends to attract those who haven’t an ounce of JavaScript knowledge. Now, on one hand, this is fantastic. However, on the flip side, it also results in a smattering of, quite frankly, disgustingly bad code (some of which I wrote myself!).
But that’s okay; frighteningly poor code that would even make your grandmother gasp is a rite of passage. The key is to climb over the hill, and that’s what we’ll discuss in today’s tutorial.
1. Methods Return the jQuery Object
It’s important to remember that most methods will return the jQuery object. This is extremely helpful, and allows for the chaining functionality that we use so often.view plaincopy to clipboardprint?
$someDiv
.attr('class', 'someClass')
.hide()
.html('new stuff');
Knowing that the jQuery object is always returned, we can use this to remove superfluous code at times. For example, consider the following code:
view plaincopy to clipboardprint?
var someDiv = $('#someDiv');
someDiv.hide();
The reason why we “cache” the location of the
The code above is perfectly fine; however, you could just as easily combine the two lines into one, while achieving the same outcome.someDivelement is to limit the number of times that we have to traverse the DOM for this element to once.
view plaincopy to clipboardprint?
var someDiv = $('#someDiv').hide();
This way, we still hide the
someDivelement, but the method also, as we learned, returns the jQuery object — which is then referenced via the
someDivvariable.
2. The Find Selector
As long as your selectors aren’t ridiculously poor, jQuery does a fantastic job of optimizing them as best as possible, and you generally don’t need to worry too much about them. However, with that said, there are a handful of improvements you can make that will slightly improve your script’s performance.One such solution is to use the
find()method, when possible. The key is stray away from forcing jQuery to use its Sizzle engine, if it’s not necessary. Certainly, there will be times when this isn’t possible — and that’s okay; but, if you don’t require the extra overhead, don’t go looking for it.
view plaincopy to clipboardprint?
// 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();
The latest modern browsers have support for
However, older browsers, namely IE6/IE7, understandably don’t provide support. What this means is that these more complicated selectors trigger jQuery’s full Sizzle engine, which, though brilliant, does come along with a bit more overhead.QuerySelectorAll, which allows you to pass CSS-like selectors, without the need for jQuery. jQuery itself checks for this function as well.
Sizzle is a brilliant mass of code that I may never understand. However, in a sentence, it first takes your selector and turns it into an “array” composed of each component of your selector.
view plaincopy to clipboardprint?// Rough idea of how it works
['#someDiv, 'p'];
It then, from right to left, begins deciphering each item with regular expressions. What this also means is that the right-most part of your selector should be as specific as possible — for instance, an
idor tag name.
Bottom line, when possible:
Keep your selectors simple
Utilize the
find()method. This way, rather than using Sizzle, we can continue using the browser’s native functions.
When using Sizzle, optimize the right-most part of your selector as much as possible.
Context Instead? It’s also possible to add a context to your selectors, such as:
view plaincopy to clipboardprint?
$('.someElements', '#someContainer').hide();
This code directs jQuery to wrap a collection of all the elements with a class of
someElements— that are children of
someContainer— within jQuery. Using a context is a helpful way to limit DOM traversal, though, behind the scenes, jQuery is using the
findmethod instead.
view plaincopy to clipboardprint?
$('#someContainer')
.find('.someElements')
.hide();
Proof view plaincopy to clipboardprint?
// HANDLE: $(expr, context)
// (which is just equivalent to: $(context).find(expr)
} else {
return jQuery( context ).find( selector );
}
3. Don’t Abuse $(this)
Without knowing about the various DOM properties and functions, it can be easy to abuse the jQuery object needlessly. For instance:view plaincopy to clipboardprint?
$('#someAnchor').click(function() {
// Bleh
alert( $(this).attr('id') );
});
If our only need of the jQuery object is to access the anchor tag’s
idattribute, this is wasteful. Better to stick with “raw” JavaScript.
view plaincopy to clipboardprint?
$('#someAnchor').click(function() {
alert( this.id );
});
Please note that there are three attributes that should always be accessed, via jQuery: “src,” “href,” and “style.” These attributes require the use of
Proof view plaincopy to clipboardprint?getAttributein older versions of IE.
// 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 );
Multiple jQuery Objects Even worse is the process of repeatedly querying the DOM and creating multiple jQuery objects.
view plaincopy to clipboardprint?
$('#elem').hide();
$('#elem').html('bla');
$('#elem').otherStuff();
Hopefully, you’re already aware of how inefficient this code is. If not, that’s okay; we’re all learning. The answer is to either implement chaining, or to “cache” the location of
#elem.
view plaincopy to clipboardprint?
// 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. jQuery’s Shorthand Ready
Method
Listening for when the document is ready to be manipulated is laughably simple with jQuery.view plaincopy to clipboardprint?
$(document).ready(function() {
// let's get up in heeya
});
Though, it’s very possible that you might have come across a different, more confusing wrapping function.
view plaincopy to clipboardprint?
$(function() {
// let's get up in heeya
});
Though the latter is somewhat less readable, the two snippets above are identical. Don’t believe me? Just check the jQuery source.
view plaincopy to clipboardprint?
// HANDLE: $(function)
// Shortcut for document ready
if ( jQuery.isFunction( selector ) ) {
return rootjQuery.ready( selector );
}
rootjQueryis simply a reference to the root
jQuery(document). When you pass a selector to the jQuery function, it’ll determine what type of selector you passed: string, tag, id, function, etc. If a function was passed, jQuery will then call its
ready()method, and pass your anonymous function as the selector.
5. Keep your Code Safe
If developing code for distribution, it’s always important to compensate for any possible name clashing. What would happen if some script, imported after yours, also had a$function? Bad stuff!
The answer is to either call jQuery’s
noConflict(), or to store your code within a self-invoking anonymous function, and then pass jQuery to it.
Method 1: NoConflict view plaincopy to clipboardprint?
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';
Be careful with this method, and try not to use it when distributing your code. It would really confuse the user of your script! :)
Method 2: Passing jQuery view plaincopy to clipboardprint?
(function($) {
// Within this function, $ will always refer to jQuery
})(jQuery);
The final parens at the bottom call the function automatically –
function(){}(). However, when we call the function, we also pass jQuery, which is then represented by
$.
Method 3: Passing $ via the
ReadyMethod view plaincopy to clipboardprint?
jQuery(document).ready(function($) {
// $ refers to jQuery
});
// $ is either undefined, or refers to some other library's function.
6. Be Smart
Remember – jQuery is just JavaScript. Don’t assume that it has the capacity to compensate for your bad coding. :)This means that, just as we must optimize things such as JavaScript
forstatements, the same is true for jQuery’s
eachmethod. And why wouldn’t we? It’s just a helper method, which then creates a
forstatement behind the scenes.
view plaincopy to clipboardprint?
// 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;
}
Awful view plaincopy to clipboardprint?
someDivs.each(function() {
$('#anotherDiv')[0].innerHTML += $(this).text();
});
Searches for
anotherDivfor each iteration
Grabs the innerHTML property twice
Creates a new jQuery object, all to access the text of the element.
Better view plaincopy to clipboardprint?
var someDivs = $('#container').find('.someDivs'),
contents = [];
someDivs.each(function() {
contents.push( this.innerHTML );
});
$('#anotherDiv').html( contents.join('') );
This way, within the
each(for) method, the only task we're performing is adding a new key to an array…as opposed to querying the DOM, grabbing the
innerHTMLproperty of the element twice, etc.
This tip is more JavaScript-based in general, rather than jQuery specific. The point is to remember that jQuery doesn't compensate for poor coding.
Document Fragments While we're at it, another option for these sorts of situations is to use document fragments.
view plaincopy to clipboardprint?
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 );
The key here is that there are multiple ways to accomplish simple tasks like this, and each have their own performance benefits from browser to browser. The more you stick with jQuery and learn JavaScript, you also might find that you refer to JavaScript's native properties and methods more often. And, if so, that's fantastic!
jQuery provides an amazing level of abstraction that you should take advantage of, but this doesn't mean that you're forced into using its methods. For example, in the fragment example above, we use jQuery's
eachmethod. If you prefer to use a
foror
whilestatement instead, that's okay too!
With all that said, keep in mind that the jQuery team have heavily optimized this library. The debates about jQuery's
each()vs. the native
forstatement are silly and trivial. If you are using jQuery in your project, save time and use their helper methods. That's what they're there for! :)
7. AJAX Methods
If you're just now beginning to dig into jQuery, the various AJAX methods that it makes available to us might come across as a bit daunting; though they needn't. In fact, most of them are simply helper methods, which route directly to$.ajax.
get
getJSON
post
ajax
As an example, let's review
getJSON, which allows us to fetch JSON.
view plaincopy to clipboardprint?
$.getJSON('path/to/json', function(results) {
// callback
// results contains the returned data object
});
Behind the scenes, this method first calls
$.get.
view plaincopy to clipboardprint?
getJSON: function( url, data, callback ) {
return jQuery.get(url, data, callback, "json");
}
$.getthen compiles the passed data, and, again, calls the "master" (of sorts)
$.ajaxmethod.
view plaincopy to clipboardprint?
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
});
}
Finally,
$.ajaxperforms a massive amount of work to allow us the ability to successfully make asynchronous requests across all browsers!
What this means is that you can just as well use the
Just Dandy view plaincopy to clipboardprint?$.ajaxmethod directly and exclusively for all your AJAX requests. The other methods are simply helper methods that end up doing this anyway. So, if you want, cut out the middle man. It's not a significant issue either way.
$.getJSON('path/to/json', function(results) {
// callback
// results contains the returned data object
});
Microscopically More Efficient view plaincopy to clipboardprint?
$.ajax({
type: 'GET',
url : 'path/to/json',
data : yourData,
dataType : 'json',
success : function( results ) {
console.log('success');
})
});
8. Accessing Native Properties and Methods
So you've learned a bit of JavaScript, and have learned that, for instance, on anchor tags, you can access attribute values directly:view plaincopy to clipboardprint?
var anchor = document.getElementById('someAnchor');
//anchor.id
// anchor.href
// anchor.title
// .etc
The only problem is that this doesn't seem to work when you reference the DOM elements with jQuery, right? Well of course not.
Won't Work view plaincopy to clipboardprint?
// Fails
var id = $('#someAnchor').id;
So, should you need to access the
hrefattribute (or any other native property or method for that matter), you have a handful of options.
view plaincopy to clipboardprint?
// 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;
The
getmethod is particularly helpful, as it can translate your jQuery collection into an array.
9. Detect AJAX Requests with PHP
Certainly, for the huge majority of our projects, we can't only rely on JavaScript for things like validation, or AJAX requests. What happens when JavaScript is turned off? For this very reason, a common technique is to detect whether an AJAX request has been made with your server-side language of choice.jQuery makes this ridiculously simple, by setting a header from within the
$.ajaxmethod.
view plaincopy to clipboardprint?
// 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");
}
With this header set, we can now use PHP (or any other language) to check for this header, and proceed accordingly. For this, we check the value of
$_SERVER['HTTP_X_REQUESTED_WITH'].
Wrapper view plaincopy to clipboardprint?
function isXhr() {
return $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest';
}
10. jQuery and $
Ever wonder why/how you can usejQueryand
$interchangeably? To find your answer, view the jQuery source, and scroll to the very bottom. There, you'll see:
window.jQuery = window.$ = jQuery;
The entire jQuery script is, of course, wrapped within a self-executing function, which allows the script to limit the number of global variables as much as possible. What this also means, though, is that the jQuery object is not available outside of the wrapping anonymous function.
To fix this, jQuery is exposed to the global
windowobject, and, in the process, an alias -
$- is also created.
11. Conditionally Loading jQuery
HTML5 Boilerplate offers a nifty one-liner that will load a local copy of jQuery if, for some odd reason, your chosen CDN is down.view plaincopy to clipboardprint?
<!-- 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>
To "phrase" the code above: if window.jQuery is undefined, there must have been a problem downloading the script from the CDN. In that case, proceed to the right side of the
&&operator, and insert a script linking to a local version of jQuery.
12. jQuery Filters
Premium Members: Download this Video ( Must be logged in)Subscribe to our YouTube page to watch all of the video tutorials!
view plaincopy to clipboardprint?
<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>
Note:
jQuery.expr[':']is simply an alias for
jQuery.expr.filters.
13. A Single Hover Function
As of jQuery 1.4, we can now pass only a single function to thehovermethod. Before, both the in and outmethods were required.
Before view plaincopy to clipboardprint?
$('#someElement').hover(function() {
// mouseover
}, function() {
// mouseout
});
Now view plaincopy to clipboardprint?
$('#someElement').hover(function() {
// the toggle() method can be used here, if applicable
});
Note that this isn't an old vs. new deal. Many times, you'll still need to pass two functions to
hover, and that's perfectly acceptable. However, if you only need to toggle some element (or something like that), passing a single anonymous function will save a handful of characters or so!
14. Passing an Attribute Object
As of jQuery 1.4, we can now pass an object as the second parameter of the jQuery function. This is helpful when we need to insert new elements into the DOM. For example:Before view plaincopy to clipboardprint?
$('<a />')
.attr({
id : 'someId',
className : 'someClass',
href : 'somePath.html'
});
After view plaincopy to clipboardprint?
$('</a>', {
id : 'someId',
className : 'someClass',
href : 'somePath.html'
});
Not only does this save a few characters, but it also makes for cleaner code. In addition to element attributes, we can even pass jQuery specific attributes and events, like
clickor
text.
相关文章推荐
- 14个非常有用的jquery技巧,注意事项和最佳实践
- AD排错最佳实践―― 技巧与捷径-笔记
- 关于Android最佳性能实践——布局优化技巧学习笔记
- 14个有用的Jquery技巧分享
- Javascript笔记:(实践篇)从jQuery插件技巧说起-深切解析extend办法(中篇)
- 45 Useful JavaScript Tips, Tricks and Best Practices(有用的JavaScript技巧,技巧和最佳实践)
- 45个有用的JavaScript技巧,窍门和最佳实践
- 45个有用的JavaScript技巧,技巧和最佳实践
- jQuery最佳实践操作与技巧
- Android最佳性能实践(四)——布局优化技巧
- jQuery编程的最佳实践
- jQuery最佳实践
- 超实用的JavaScript技巧及最佳实践(一)
- (优化)Android最佳性能实践(四)——布局优化技巧
- ADO.NET 的最佳实践技巧
- JQuery最佳实践
- 七个相关jQuery的最佳实践
- Maven学习笔记十七:Maven坐标和依赖(最佳实践之优化依赖)