Spacing
Comments
Equality
Blocks
Function Calls
Arrays & Objects
Assignment
Type Checks
Strings
(Just plain bad code)
function validateContactForm() {
var result = "";
if($('#contact_form #name').val()=="") {
result = false;
return false;
}
if($("#contact_form").find('#address')[0].value!="")result=true;
return result;
}
function doesJQElementExistInDOM(jQueryElement)
{
if(jQueryElement.length)
return true;
else
return false;
}
function show()
{
for (var i = 0; i < arguments.length; i++) {
jq(arguments[i]).show();
}
}
function hide()
{
for (var i = 0; i < arguments.length; i++) {
jq(arguments[i]).hide();
}
}
(Collection methods should be called on a jQuery object)
function enumerate( elems, start ) {
for ( var i = 0; i < elems.length; i++ ) {
elems.eq( i ).prepend( "" + ( i + start ) + " " );
}
};
// This is no fun!
enumerate( $("li"), 1 );
// Wouldn't you much rather do this?
$("li").enumerate( 1 );
// Create a new jQuery collection method.
$.fn.enumerate = function() {
// Code goes here.
};
// This doesn't error, but it does nothing and returns undefined.
$("li").enumerate();
// Error: cannot call method 'css' of undefined!
$("li").enumerate().css( "color", "red" );
// A simple test.
var elems = $("li");
$.fn.enumerate = function() {
// What, exactly, is `this`? I have a nagging suspicion...
console.log( this === elems );
};
// Logs true!
elems.enumerate();
// Create a chainable jQuery collection method.
$.fn.enumerate = function() {
return this;
};
// Does nothing, but returns the same jQuery object it was called on.
$("li").enumerate();
// Because of this, it's chainable!
$("li").enumerate().css( "color", "red" );
(Plugins implicitly iterate… by explicitly iterating)
// No explicit iteration in the plugin...
$.fn.enumerate = function( start ){
this.prepend( "" + start + " " );
return this;
};
// ...means no implicit iteration when it's used.
$("li").enumerate( 1 );
// Explicit iteration in the plugin...
$.fn.enumerate = function( start ){
for ( var i = 0; i < this.length; i++ ) {
this.eq( i ).prepend( "" + ( i + start ) + " " );
}
return this;
};
// ...means implicit iteration when it's used!
$("li").enumerate( 1 );
// But you should explicitly iterate using jQuery's .each().
$.fn.enumerate = function( start ){
this.each(function(i){
$(this).prepend( "" + ( i + start ) + " " );
});
return this;
};
// Roll the return up to remove the extra, unnecessary line, and you
// have the basic "Chainable jQuery Collection Method" pattern:
$.fn.enumerate = function( start ){
return this.each(function(i){
$(this).prepend( "" + ( i + start ) + " " );
});
};
How do you make a method “end”-able?
.end Method
// In brief:
$("ul").find( "li" ).addClass( "fancy" ).end().addClass( "selected" );
// Select all UL elements.
$("ul")
// From there, find all LI descendants.
.find( "li" )
// Add a class to each selected LI element.
.addClass( "fancy" )
// Revert back to the previous collection.
.end()
// Add a class to each selected UL element.
.addClass( "selected" );
.pushStack Method
// The most basic "end"-able collection method.
$.fn.listitems = function() {
var elems = this.find( "li" );
return this.pushStack( elems );
};
// Just like before!
$("ul")
.listitems()
.addClass( "fancy" )
.end()
.addClass( "selected" );
// An "end"-able collection method with an optional selector.
$.fn.listitems = function( selector ){
var elems = this.find( "li" );
if ( selector ) {
elems = elems.filter( selector );
}
return this.pushStack( elems, "listitems", selector || "" );
};
// Fancy!
$("ul")
.listitems( ":first-child" )
.addClass( "fancy" )
.end()
.addClass( "selected" );
// Our basic, chainable, "enumerate" method.
$.fn.enumerate = function( start ) {
return this.each(function(i){
$(this).prepend( "" + ( i + start ) + " " );
});
};
// Enumerate the listitems, effectively "setting" values.
$("li").enumerate( 1 );
// Only return the appropriate value from the first selected element.
$.fn.getEnumerateStartingValueOMGLongName = function() {
var val = this.eq( 0 ).children( "b" ).eq( 0 ).text();
return Number( val );
};
// Because this doesn't return a jQuery object, it's not chainable!
$("li").getEnumerateStartingValueOMGLongName();
// A jQuery collection method that both "sets" and "gets."
$.fn.enumerate = function( start ) {
if ( typeof start !== "undefined" ) {
// Since `start` value was provided, enumerate and return
// the initial jQuery object to allow chaining.
return this.each(function(i){
$(this).prepend( "" + ( i + start ) + " " );
});
} else {
// Since no `start` value was provided, function as a
// getter, returing the appropriate value from the first
// selected element.
var val = this.eq( 0 ).children( "b" ).eq( 0 ).text();
return Number( val );
}
};
// This is ok if it's just for you.
$.fn.enumerate = function( start ){
return this.each(function(i){
$(this).prepend( "" + ( i + start ) + " " );
});
};
// If you're sharing with others, you need to wrap your code
// in an IIFE (Immediately-Invoked Function Expression).
(function($){
$.fn.enumerate = function( start ){
return this.each(function(i){
$(this).prepend( "" + ( i + start ) + " " );
});
};
})(jQuery);
// Closures are great, because they allow you a private scope in
// which you can store "private" variables and functions.
/*!
* jQuery Tiny Pub/Sub - v0.3pre - 11/4/2010
* http://benalman.com/
*
* Copyright (c) 2010 "Cowboy" Ben Alman
* Dual licensed under the MIT and GPL licenses.
* http://benalman.com/about/license/
*/
(function($){
var o = $({});
$.subscribe = function(){
o.bind.apply( o, arguments );
};
$.unsubscribe = function(){
o.unbind.apply( o, arguments );
};
$.publish = function(){
o.trigger.apply( o, arguments );
};
})(jQuery);
// What's wrong with this "jQuery plugin"? Hint: it's not
// the code itself.
(function($){
$.log = function( msg ) {
if ( $.log.enabled && window.console ) {
console.log( msg );
}
};
$.log.enabled = true;
})(jQuery);
// Don't attach arbitrary methods to $ unless they're REALLY
// jQuery plugins.
var log = (function(){
function fn( msg ) {
if ( log.enabled && window.console ) {
console.log( msg );
}
};
fn.enabled = true;
return fn;
})();
// This method will never be called on a collection of elements,
// it's just a utility method.
$.deparam = function( str ) {
var obj = {};
$.each( str.split( "&" ), function(i,pair){
var nv = pair.split( "=" );
obj[ nv[0] ] = nv[ 1 ];
});
return obj;
};
$.deparam( "a=1&b=2&c=3" ); // { a: "1", b: "2", c: "3" }
// For jQuery utility methods, this works.
$.myPlugin = function() {
// Code goes here.
};
$.myPlugin.submethod = function() {
// Code goes here.
};
$.myPlugin();
$.myPlugin.submethod();
// For jQuery collection methods, this doesn't work.
$.fn.myPlugin = function() {
// Code goes here.
};
$.fn.myPlugin.submethod = function() {
// Code goes here.
};
$("li").myPlugin(); // While this works great...
$("li").myPlugin.submethod(); // This ain't gonna happen.
// This kind of thing is also no good. It's technically possible
// (with a lot of work) but it's confusing. For example, how do
// you keep track of chaining? What does .end() do? No good.
$("li").myPlugin().submethod();
// Of course you can do this (and a whole lot more), using the
// jQuery UI Widget Factory, and it works great.
$("li").myPlugin( "submethod", options );
// But for jQuery collection methods, this is usually sufficient.
$.fn.myPluginSubmethod = function() {
// Code goes here.
};
$("li").myPluginSubmethod();