• Stars
    star
    111
  • Rank 314,510 (Top 7 %)
  • Language
  • Created over 11 years ago
  • Updated over 10 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Pragmatic jQuery Style

Pragmatic jQuery Style

Why jQuery Style?

  • 80% of the lifetime cost of a piece of software goes to maintenance.
  • Hardly any software is maintained for its whole life by the original author.
  • Code conventions improve the readability of the software, allowing engineers to understand new code more quickly and thoroughly.
  • If you ship your source code as a product, you need to make sure it is as well packaged and clean as any other product you create.

Plugin Name

lowercase, avoid multiple words.

// bad
jquery.string.js
jquery.observer.js
jquery.promise.js

// good
string.js
observer.js
promise.js

Plugin Skeleton

// pluginName.js

(function (factory) {
    if (typeof define === 'function') {
        define(['$'], factory);
    } else {
        factory($);
    }
})(function ($) {
     'use strict';
     var pluginName = 'pluginName';
    // balabala...
})

There are some kinds of jQuery plugins:

  • $.pluginName( { name:"value" } ); Attach to $ because they did not want to create a global, but just indicate it is jQuery-related functionality. They do not do anything with node lists though.

    // pluginName.js
    
    (function (factory) {
        if (typeof define === 'function') {
        ...
    })(function ($) {
        'use strict';
        var pluginName = 'defaultPluginName';
    
        function plugin( options ){
            // ...
        } 
    
        $[pluginName] = plugin;
    })
  • $(".foo").pluginName( { name:"value" } ); Attach to $.fn because they want to participate in the chained API style when operating with a node list.

    // pluginName.js
    
    (function (factory) {
        if (typeof define === 'function') {
        ...
    })(function ($) {
        'use strict';
        var pluginName = 'defaultPluginName';
        
        function plugin( element, options ) {
            // ...
        }
    
        $.fn[pluginName] = function ( options ) {
            return this.each(function () {
                // ...
            })
                
        });
    })
  • $.ajax( { dataType:"jsonpi" } ); custom jQuery ajax request http://api.jquery.com/extending-ajax/

    // pluginName.js
    
    (function (factory) {
        if (typeof define === 'function') {
        ...
    })(function ($) {
        'use strict';
        var pluginName = 'jsonpi';
        
        $.ajaxTransport( pluginName , function(opts, originalOptions, jqXHR) {
            // ...
        });
    })
  • $( 'div:inline' ); custom jQuery selector

    // pluginName.js
    
    (function (factory) {
        if (typeof define === 'function') {
        ...
    })(function ($) {
        'use strict';
        var pluginName = 'defaultPluginName';
        
        $.expr[':'][pluginName] = function(element) {
            return $(element).css('display') === 'inline';
        };
    
        $(':inline');  // Selects ALL inline elements
        $('a:inline'); // Selects ALL inline anchors
    })
  • $( '#element' ).on('cumstomEvent', function(){}); custom jQuery Event

    // pluginName.js
    
    (function (factory) {
        if (typeof define === 'function') {
        ...
    })(function ($) {
        'use strict';
        var eventName = 'customEventName';
        
        $.event.special[eventName] = {
            // called when the event is bound
            setup: function(data, namespaces) {
                var $this = $(this);
            },
            // called when event is unbound
            teardown: function(namespaces) {
                var $this = $(this);
            },
            // called when event is dispatched
            handler: function(event) {
                var $this = $(this);
            },
            // similar to setup, but is called for each event being bound
            add: function(event) {
                var $this = $(this);
            },
            // similar to teardown, but is called for each event being unbound
            remove: function(event) {
                var $this = $(this);
            }
        };
    
        // bind custom event
        $("#element").on("customEventName.myNamespace", function(evt) {});
        // remove all events under the myNamespace namespace
        $("#element").off(".myNamespace");
    
    })
  • $( 'textarea.foo' ).val(); custom form element value hook

    // valHooks.js
    
    (function (factory) {
        if (typeof define === 'function') {
        ...
    })(function ($) {
        'use strict';
    
        $.valHooks.textarea = {
            get: function( elem ) {
                return elem.value.replace( /\r?\n/g, "\r\n" );
            }
        };
    
    })

Indentation

The unit of indentation is four spaces.

arr.forEach(function(val, key){
....// indentation with four spaces
});

Variable Name

lowerCamelCase

var thisIsMyVal;
var md5Encoder;
var xmlReader;
var httpServer;

Method Name

lowerCamelCase

function thisIsMyFunction() {
    // balabala
}
// Some special cases
getMd5() instead of getMD5()
getHtml() instead of getHTML()
getJsonResponse() instead of getJSONResponse()
parseXmlContent() instead of parseXMLContent()

Why lowerCamelCase?

We know that when you write Ruby or Python, you use under_scored method names and UpperCamelCase class names. But JavaScript isn't Ruby or Python.

Consider:

  • In browsers, all methods are lowerCamelCase.
  • In node.js's standard library, all methods are lowerCamelCase.
  • In commonjs, all methods are lowerCamelCase.
  • In jQuery, all methods are lowerCamelCase.
  • In MooTools, all methods are lowerCamelCase.
  • In Prototype, all method are lowerCamelCase.
  • In YUI, all method are lowerCamelCase.
  • In JavaScript: The Good Parts, all methods are lowerCamelCase.

We not saying you must write JavaScript a certain way. Do what makes you the most comfortable, write code that is fun to write. But if you're trying to figure out what everyone else is doing, they're doing lowerCamelCase.

Constant

var LOCALHOST = "http://localhost";
var REMORT_PORT = "8080";

Class Name

UpperCamelCase

var Greeter = Class.extend({
    name: null,
 
    _constructor: function(name) {
        this.name = name;
    },
 
    greet: function() {
        alert('Good Morning ' + this.name);
    }
});

Variables Declare

var a = "alpha";
var b = "beta";
var c = "chi";

Why?

var a = "alpha",
    b = "beta" // <-- note the forgotten comma
    c = "chi"; // <-- and now c is global

Leading Commas

var hero = {
    firstName: 'Bob'
  , lastName: 'Parr'
  , heroName: 'Mr. Incredible'
  , superPower: 'strength'
};

Why?

var hero = {
  firstName: 'Bob',
  lastName: 'Parr',
  heroName: 'Mr. Incredible', // <-- forgot remove comma, when comment the last item
  //superPower: 'strength'    
};

jQuery Object

Prefix jQuery object variables with a $. The dollar notation on all jQuery-related variables helps us easily distinguish jQuery variables from standard JavaScript variables at a glance.

// bad
var sidebar = $('.sidebar');
var that = $(this);

// good
var $sidebar = $('.sidebar');
var $this = $(this);

Method Chains

Use indentation when making long method chains, and avoid more than 6 methods chained. Less method chains, more friendly debugging.

// bad
$('#items').find('.selected').highlight().end().find('.open').updateCount();

// good
$('#items')
.find('.selected')
  .highlight()
  .end()
.find('.open')
  .updateCount();

Determine jQuery Object

Determine if an object is a jQuery object

// bad (fast)
if( obj.jquery ){}

// good (slow)
if( obj instanceof jQuery){}

Document Ready

// bad
$(function() {
    // Handler for .ready() called.
});

// good
$(document).ready(function() {
    // Handler for .ready() called.
});

Event Bind

// bad
$( "#members li a" ).bind( "click", function( e ) {} ); 

// good
$( "#members li a" ).on( "click", function( e ) {} ); 

// good
$( "#members li a" ).click( function( e ) {} ); 

Event Live

// bad, .live() deprecated jQuery 1.7, removed jQuery 1.9
$( "#members li a" ).live( "click", function( e ) {} );

// good
$( document ).on( "click", "#members li a", function( e ) {} ); 

Event Delegate

// bad, as of jQuery 1.7, .delegate() has been superseded by the .on() method
$( "#members" ).delegate( "li a", "click", function( e ) {} );

// good
$( "#members" ).on( "click", "li a", function( e ) {} ); 

Event Prevent

// bad
$(".btn").click(function(event){
    // @more: http://fuelyourcoding.com/jquery-events-stop-misusing-return-false/
    return false;
});

// good
$(".btn").click(function(event){
    event.preventDefault();
});

// good
$(".btn").click(function(event){
    event.preventDefault();
    event.stopImmediatePropagation()
});

// good
$(".btn").click(function(event){
    event.stopPropagation();
    event.preventDefault();
    event.stopImmediatePropagation();
});

Element Create

// bad
$('<a/>')  
  .attr({  
    id : 'someId',  
    className : 'someClass',  
    href : 'somePath.html'  
  });

// good
$('<a/>', {  
    id : 'someId',  
    className : 'someClass',  
    href : 'somePath.html'  
}); 

Element Exists

// bad
if ($('#myElement')[0]) {  
    // balabala...
}  

// good
if ($('#myElement').length) {  
    // balabala... 
}

Element Access

// bad
$('#myElement').click(funtion(){
    var id = $(this).attr('id');
})

// good
$('#myElement').click(funtion(){
    var id = this.id;
})

Number Compare

var a = '1';
var b = 1;

// bad
parseInt(a) === b

// good, implicit coercion
+a === b

// better, expressive conversion, and conversion over coercion
Number(a) === b

Array Traversal

var array = new Array(100);
// bad (faster)
for (var i=0,l=array.length; i<l; i++) {
    console.log(i, array[i]);    
}
  
// good (slow)
$.each (array, function (i, value) {  
    console.log(i, value);  
});

// better (fast), use es5-shim(https://github.com/kriskowal/es5-shim) for legacy JavaScript engines
array.forEach(function(value, i){
    console.log(i, value);
});
 

Async Programing

// bad
$.ajax({
    url: "cgi/example"
    , success: function() { alert("success"); }
    , error: function() { alert("error"); }
    , complete: function() { alert("complete"); }
});

// good
var jqxhr = $.ajax( "cgi/example" )
    .done(function() { alert("success"); })
    .fail(function() { alert("error"); })
    .always(function() { alert("complete"); });

Type Determine

var obj = {};
var arr = [];
var reg = /test/g;
var fn = function(){};

// bad
typeof obj === 'object'
typeof arr === 'array'
typeof fn === 'function'
reg instanceof RegExp

// good 
// http://api.jquery.com/jQuery.type/
$.type(obj) === 'object'
$.type(arr) === 'array'
$.type(reg) === 'regexp'
$.type(fn) === 'function'

// better
$.isPlainObject(obj)
$.isArray(arr)
$.isFunction(fn)

Ajax Retry

// not bad, inspried by http://zeroedandnoughted.com/defensive-ajax-and-ajax-retries-in-jquery/
$.ajax({
    url : 'path/to/url',
    type : 'get',
    data :  {name : 'value'},
    dataType : 'json',
    timeout : 25000,
    tryCount : 0,
    retryLimit : 3,
    success : function(json) {
        //do something
    },
    error : function(xhr, textStatus, errorThrown ) {
        if ($.inArray(textStatus, ['timeout', 'abort', 'error']) > -1) {
            this.tryCount++;
            if (this.tryCount <= this.retryLimit) {
                //try again
                return $.ajax(this);
            }
            return alert('Oops! There was a problem, please try again later.');
        }
    }
});

// better, inspried by https://github.com/mberkom/jQuery.retryAjax
$.retryAjax = function (ajaxParams) {
	var errorCallback;
	ajaxParams.tryCount = ajaxParams.tryCount > 0 ? ajaxParams.tryCount : 0;
	ajaxParams.retryLimit = ajaxParams.retryLimit > 0 : ajaxParams.retryLimit : 2;
	// Custom flag for disabling some jQuery global Ajax event handlers for a request
	ajaxParams.suppressErrors = true;
	
	if (ajaxParams.error) {
	    errorCallback = ajaxParams.error;
	    ajaxParams.error = null;
	} else {
	    errorCallback = $.noop;
	}
	
	ajaxParams.complete = function (jqXHR, textStatus) {
	    if ($.inArray(textStatus, ['timeout', 'abort', 'error']) > -1) {
	        this.tryCount++;
	        if (this.tryCount <= this.retryLimit) {
	            // fire error handling on the last try
	            if (this.tryCount === this.retryLimit) {
	                this.error = errorCallback;
	                this.suppressErrors = null;
	            }
	            //try again
	            $.ajax(this);
	            return true;
	        }
	
	        alert('Oops! There was a problem, please try again later.');
	        return true;
	    }
	};

	$.ajax(ajaxParams);
};

$.retryAjax({
	url : 'path/to/url',
    type : 'get',
    data :  {name : 'value'},
    dataType : 'json',
    timeout : 25000,
    success : function(json) {
        //do something
    }
})

Performance

  • Cache jQuery lookups

    // bad
    function setSidebar() {
      $('.sidebar').hide();
    
      // ...stuff...
    
      $('.sidebar').css({
        'background-color': 'pink'
      });
    }
    
    // good
    function setSidebar() {
      var $sidebar = $('.sidebar');
      $sidebar.hide();
    
      // ...stuff...
    
      $sidebar.css({
        'background-color': 'pink'
      });
    }
  • For DOM queries use Cascading $('.sidebar ul') or parent > child $('.sidebar > .ul'). jsPerf

  • Use find with scoped jQuery object queries.

    // bad
    $('.sidebar', 'ul').hide();
    
    // bad
    $('.sidebar').find('ul').hide();
    
    // good
    $('.sidebar ul').hide();
    
    // good
    $('.sidebar > ul').hide();
    
    // good (slower)
    $sidebar.find('ul');
    
    // good (faster)
    $($sidebar[0]).find('ul');
  • Use event delegation with list of elements.

    <ul>
    	<li>list1</li>
    	<li>list2</li>
    	<li>list3</li>
    	<li>list4</li>
    	<li>list5</li>
    </ul>	
    // bad
    $("ul li").on("click", function() {
        $(this).text("aha");
    });
    
    // good
    $("ul").on("click", "li", function() {
        $(this).text("aha");
    });

Ref

More Repositories

1

halogen

A collection of loading spinners with React.js
JavaScript
1,596
star
2

boron

A collection of dialog animations with React.js
JavaScript
1,481
star
3

react-timesheet

Time Sheet Component for React
JavaScript
259
star
4

react-ajax

Ajax Request Component for React.
JavaScript
108
star
5

node-optimage

Image optimizer, PNG, JPEG and GIFimage compress on OS X, Linux, FreeBSD and Windows
JavaScript
67
star
6

domkit

Toolkit for DOM
JavaScript
61
star
7

node-regexp

New RegExp Style for Node.js
JavaScript
59
star
8

ming

High-productivity JavaScript Solution
JavaScript
51
star
9

jsprofiler

javascript profiler
JavaScript
45
star
10

UglifyJS-java

JavaScript parser / mangler / compressor / beautifier library for for Java
JavaScript
42
star
11

react-native-web-example

React Native Web Example
JavaScript
40
star
12

react-image

Enhanced Image Component for React.
JavaScript
36
star
13

hp

HTTP Proxy Kit
JavaScript
33
star
14

react-mq

Media Query Component for React.
JavaScript
26
star
15

react-storage

Storage Component for React
JavaScript
25
star
16

know-your-chrome

know your chrome
C++
21
star
17

pre

An enjoyable css framework use less
JavaScript
19
star
18

node-webp-bin

WebP Node.js wrapper that makes it seamlessly available as a local dependency on OS X, Linux and Windows.
JavaScript
16
star
19

commons-json

A high performance JSON library for java
Java
13
star
20

barium

Pragmatic Styling with React.js
JavaScript
13
star
21

haste-resolver-webpack-plugin

Haste Resolver Webpack Plugin
JavaScript
12
star
22

react-signals

Signals Component for React.
JavaScript
11
star
23

react-pull

Pull Component for React
JavaScript
8
star
24

arsenic

Backgroud component for React
JavaScript
8
star
25

react-native-web-exploding-hearts

React Native Web Exploding Hearts Example
JavaScript
8
star
26

mobi

Framework for developing mobile only projects on the web.
JavaScript
7
star
27

google-cli

Google CLI.
JavaScript
7
star
28

requirejs-tmpl

Require.js plugin for templates, it's a tooling not a library
JavaScript
7
star
29

fanta

when function met fanta.
JavaScript
7
star
30

ship

Code manager client
JavaScript
5
star
31

morse

Morse Code Game (WIP)
JavaScript
4
star
32

universal-react-starter

A professional universal (isomorphic) react starter for building web apps.
JavaScript
4
star
33

less2

LESS 2.0
JavaScript
4
star
34

yuanyan.github.io

Website
JavaScript
4
star
35

ladybug

Making The Mobile Web Faster
JavaScript
3
star
36

jquery-sonar

jQuery sonar effect plugin
JavaScript
3
star
37

moon

js&css file server on top of nodejs
JavaScript
3
star
38

404

QQ Connect 404 Page
3
star
39

haste-resolver

Haste Resolver
JavaScript
3
star
40

jazz

jazz is js
JavaScript
3
star
41

react-native-web-hacker-news

Objective-C
3
star
42

react-native-generator

JavaScript
3
star
43

ninjs

Javascript Ninja's Garden
JavaScript
3
star
44

node-isabspath

Predicate method for testing whether a path is absolute
JavaScript
3
star
45

Ning

Node.js Web Application Driver (WIP)
JavaScript
3
star
46

commons-algorithm

commons.algorithm
Java
2
star
47

jquery-jsonview

json data visualization for jquery
JavaScript
2
star
48

sublime-mod

Mod for Sublime Text
Python
2
star
49

soundbox.js

JavaScript library for audio processing(WIP)
JavaScript
2
star
50

tencent-hackathon-scoring

Tencent Hackathon Scoring Application
JavaScript
2
star
51

fitnect

Tencent Hackthon Work
JavaScript
2
star
52

stylesheet-loader

JavaScript
2
star
53

select

A micro css selector engine
JavaScript
1
star
54

mircotask

High performance task scheduler
JavaScript
1
star
55

webpack-html-plugin

JavaScript
1
star
56

node-unixifypath

Unixify pathname for Node.js
JavaScript
1
star
57

resume

My Resumรฉ is open
CSS
1
star
58

square-ui

Square User Interface Kit For Mobile Web (Work In Process)
CSS
1
star
59

jquery-storage

cross browser storage module for jquery
JavaScript
1
star