50个实用的JavaScript、JQ和jQuery前端开发技巧

发表时间: 2018-03-27 15:12

技巧1:在document文档就绪时执行JavaScript代码

<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>

<script>

// Different ways to achieve the Document Ready event

// With jQuery

$(document).ready(function(){ /* ... */});

// Short jQuery

$(function(){ /* ... */});

// Without jQuery (doesn't work in older IE versions)

document.addEventListener('DOMContentLoaded',function(){

// Your code goes here

});

// The Trickshot (works everywhere):

r(function(){

alert('DOM Ready!');

})

function r(f){/in/.test(document.readyState)?setTimeout('r('+f+')',9):f()}

</script>

技巧2:route的使用

<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>

<script>

var route = {

_routes : {}, // The routes will be stored here

add : function(url, action){

this._routes[url] = action;

},

run : function(){

jQuery.each(this._routes, function(pattern){

if(location.href.match(pattern)){

// "this" points to the function to be executed

this();

}

});

}

}

// Will execute only on this page:

route.add('002.html', function(){

alert('Hello there!')

});

route.add('products.html', function(){

alert("this won't be executed :(")

});

// You can even use regex-es:

route.add('.*.html', function(){

alert('This is using a regex!')

});

route.run();

</script>

技巧3:AND技巧的使用

&&操作符的特点是如果操作符左边的表达式是false,那么它就不会再判断操作符右边的表达式了。

所以:

// Instead of writing this:

if($('#elem').length){

// do something

}

// You can write this:

$('#elem').length && log("doing something");

技巧4:is()方法

// First, cache the element into a variable:

var elem = $('#elem');

// Is this a div?

elem.is('div') && log("it's a div");

// Does it have the bigbox class?

elem.is('.bigbox') && log("it has the bigbox class!");

// Is it visible? (we are hiding it in this example)

elem.is(':not(:visible)') && log("it is hidden!");

// Animating

elem.animate({'width':200},1);

// is it animated?

elem.is(':animated') && log("it is animated!");

上面的代码用来判断是否是动画。

技巧5:计算你的网页文件中一共有多个元素

方法:$("*").length属性

// How many elements does your page have?

log('This page has ' + $('*').length + ' elements!');

技巧6:使用exist()方法

/ Old way

log($('#elem').length == 1 ? "exists!" : "doesn't exist!");

// Trickshot:

jQuery.fn.exists = function(){ return this.length > 0; }

log($('#elem').exists() ? "exists!" : "doesn't exist!");

技巧7:jQuery方法$()第二个参数

// Select an element. The second argument is context to limit the search

// You can use a selector, jQuery object or dom element

$('li','#firstList').each(function(){

log($(this).html());

});

log('-----');

// Create an element. The second argument is an

// object with jQuery methods to be called

var div = $('<div>',{

"class": "bigBlue",

"css": {

"background-color":"purple"

},

"width" : 20,

"height": 20,

"animate" : { // You can use any jQuery method as a property!

"width": 200,

"height":50

}

});

div.appendTo('#result');

技巧8:判断一个链接是否为外部

<ul id="links">

<li><a href="007.html">The previous tip</a></li>

<li><a href="./009.html">The next tip</a></li>

<li><a href="http://www.google.com/">Google</a></li>

</ul>

// Loop through all the links

$('#links a').each(function(){

if(this.hostname != location.hostname){

// The link is external

$(this).append('<img src="assets/img/external.png" />')

.attr('target','_blank');

}

});

有没有注意到,我们使用了hostname属性。

技巧9:end()方法

<ul id="meals"> <li> <ul class="breakfast"> <li class="eggs">No</li> <li class="toast">No</li> <li class="juice">No</li> </ul> </li> </ul>

// Here is how it is used:

var breakfast = $('#meals .breakfast');

breakfast.find('.eggs').text('Yes')

.end() // back to breakfast

.find('.toast').text('Yes')

.end()

.find('.juice').toggleClass('juice coffee').text('Yes');

breakfast.find('li').each(function(){

log(this.className + ': ' + this.textContent)

});

技巧10:阻止contextmenu默认事件,让web应用像原生的

<script>

// Prevent right clicking on this page

$(function(){

$(document).on("contextmenu",function(e){

e.preventDefault();

});

});

</script>

技巧11:有些站点可能会使你的网页在一个bar下面,我们可以这样

// Here is how it is used:

if(window != window.top){

window.top.location = window.location;

}

else{

alert('This page is not displayed in a frame. Open 011.html to see it in action.');

}

技巧12:内联样式表并不是被设置为不可改变

// Make the stylesheet visible and editable

$('#regular-style-block').css({'display':'block', 'white-space':'pre'})

.attr('contentEditable',true);

技巧13:让别人无法选择你网页的某一部分

<p class="descr">In certain situations you might want to prevent text on the page from being selectable. Try selecting this text and hit view source to see how it is done.</p>

<script>

// Prevent text from being selected

$(function(){

$('p.descr').attr('unselectable', 'on')

.css('user-select', 'none')

.on('selectstart', false);

});

</script>

技巧14:提高我们网站的性能

<!-- Case 1 - requesting jQuery from the official CDN -->

<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>

<!-- Case 2 - requesting jQuery from Google's CDN (notice the protocol) -->

<!-- <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> -->

<!-- Case 3 - requesting the latest minor 1.8.x version (only cached for an hour) -->

<!-- <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10/jquery.min.js"></script> -->

<!-- Case 4 - requesting the absolute latest jQuery version (use with caution) -->

<!-- <script src="http://code.jquery.com/jquery.min.js"></script> -->

看到了吗?从CDN中引入jQuery。真的不错。

技巧15:保证最小的DOM操作

CODE

// Bad

//var elem = $('#elem');

//for(var i = 0; i < 100; i++){

// elem.append('<li>element '+i+'</li>');

//}

// Good

var elem = $('#elem'),

arr = [];

for(var i = 0; i < 100; i++){

arr.push('<li>element '+i+'</li>');

}

elem.append(arr.join(''));

技巧16:方便的分解URL

// You want to parse this address into parts:

var url = 'http://tutorialzine.com/books/jquery-trickshots?trick=12#comments';

// The trickshot:

var a = $('<a>',{ href: url });

log('Host name: ' + a.prop('hostname'));

log('Path: ' + a.prop('pathname'));

log('Query: ' + a.prop('search'));

log('Protocol: ' + a.prop('protocol'));

log('Hash: ' + a.prop('hash'));

技巧17:使用vanilla.js

// Print the IDs of all LI items

$('#colors li').each(function(){

// Access the ID directly, instead

// of using jQuery's $(this).attr('id')

log(this.id);

});

技巧18:最优化选择器

// Let's try some benchmarks!

var iterations = 10000, i;

timer('Fancy');

for(i=0; i < iterations; i++){

// This falls back to a SLOW JavaScript dom traversal

$('#peanutButter div:first');

}

timer_result('Fancy');

timer('Parent-child');

for(i=0; i < iterations; i++){

// Better, but still slow

$('#peanutButter div');

}

timer_result('Parent-child');

timer('Parent-child by class');

for(i=0; i < iterations; i++){

// Some browsers are a bit faster on this one

$('#peanutButter .jellyTime')

技巧19:缓存你的selector

// Bad:

// $('#pancakes li').eq(0).remove();

// $('#pancakes li').eq(1).remove();

// $('#pancakes li').eq(2).remove();

// Good:

var pancakes = $('#pancakes li');

pancakes.eq(0).remove();

pancakes.eq(1).remove();

pancakes.eq(2).remove();

// Alternatively:

// pancakes.eq(0).remove().end()

// .eq(1).remove().end()

// .eq(2).remove().end();

技巧20:重复的函数只定义一次

$(document).ready(function(){

function showMenu(){

alert('Showing menu!');

// Doing something complex here

}

$('#menuButton').click(showMenu);

$('#menuLink').click(showMenu);

});

技巧21:像对待数组一样地对待jQuery对象

var arr = $('li'),

iterations = 100000;

timer('Native Loop');

for(var z=0;z<iterations;z++){

var length = arr.length;

for(var i=0; i < length; i++){

arr[i];

}

}

timer_result('Native Loop');

timer('jQuery Each');

for(z=0;z<iterations;z++){

arr.each(function(i, val) {

this;

});

}

timer_result('jQuery Each');

技巧22:当做复杂的修改时要分离元素

// Modifying in place

var elem = $('#elem');

timer('In place');

for(i=0; i &lt; iterations; i++){

elem.width(Math.round(100*Math.random()));

elem.height(Math.round(100*Math.random()));

}

timer_result('In place');

var parent = elem.parent();

// Detaching first

timer('Detached');

elem.detach();

for(i=0; i &lt; iterations; i++){

elem.width(Math.round(100*Math.random()));

elem.height(Math.round(100*Math.random()));

}

elem.appendTo(parent);

timer_result('Detached');

技巧23:不要一直等待load事件

<script>

// jQuery is loaded at this point. We can use

// event delegation right away to bind events

// even before $(document).ready:

$(document).on('click', '#clickMe', function(){

alert('Hit view source and see how this is made');

});

$(document).ready(function(){

// This is where you would usually bind event handlers,

// but as we are using delegation, there is no need to.

// $('#clickMe').click(function(){ alert('Hey!'); });

});

// Note: You should place your script tags at the bottom of the page.

// I have included them in the head only to demonstrate that we can bind

// events before document ready and before the elements are created.

</script>

技巧24:当使用js给多个元素添加样式时更好的做法是创建一个style元素

<ul id="testList">

<li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li>

</ul>

var style = $('<style>');

// Try commenting out this line, or change the color:

style.text('#testList li{ color:red;}');

// Placing it before the result section so it affects the elements

style.prependTo('#result');

技巧25:给html元素分配一个名为JS的class

$(document).ready(function(){

$('html').addClass('JS');

});

html.JS #message { display:block; }

#message {display:none;}

技巧26:监听不存在的元素上的事件

<ul id="testList"> <li>Old</li> <li>Old</li> <li>Old</li> <li>Old</li> </ul>

var list = $('#testList');

// Binding an event on the list, but listening for events on the li items:

list.on('click','li',function(){

$(this).remove();

});

// This allows us to create li elements at a later time,

// while keeping the functionality in the event listener

list.append('<li>New item (click me!)</li>');

技巧27:只使用一次事件监听

<button id="press">Press me!</ul>

var press = $('#press');

// There is a method that does exactly that, the one():

press.one('click',function(){

alert('This alert will pop up only once');

});

// What this method does, is call on() behind the scenes,

// with a 1 as the last argument:

// press.on('click',null,null,function(){alert('I am the one and only!');}, 1);

技巧28:模拟触发事件

<button id="press">Press me!</ul>

var press = $('#press');

// Just a regular event listener:

press.on('click',function(e, how){

how = how || '';

alert('The buton was clicked ' + how + '!');

});

// Trigger the click event

press.trigger('click');

// Trigger it with an argument

press.trigger('click',['fast']);

技巧29:使用触摸事件

// Define some variables

var ball = $('&lt;div id="ball"&gt;&lt;/div&gt;').appendTo('body'),

startPosition = {}, elementPosition = {};

// Listen for mouse and touch events

ball.on('mousedown touchstart',function(e){

e.preventDefault();

// Normalizing the touch event object

e = (e.originalEvent.touches) ? e.originalEvent.touches[0] : e;

// Recording current positions

startPosition = {x: e.pageX, y: e.pageY};

elementPosition = {x: ball.offset().left, y: ball.offset().top};

// These event listeners will be removed later

ball.on('mousemove.rem touchmove.rem',function(e){

e = (e.originalEvent.touches) ? e.originalEvent.touches[0] : e;

ball.css({

top:elementPosition.y + (e.pageY - startPosition.y),

left: elementPosition.x + (e.pageX - startPosition.x),

});

});

});

ball.on('mouseup touchend',function(){

// Removing the heavy *move listeners

ball.off('.rem');

});

技巧30:更好地使用on()/off()方法

<div id="holder"> <button id="button1">1</button> <button id="button2">2</button> <button id="button3">3</button> <button id="button4">4</button> <button id="clear" style="float: right;">Clear</button> </div>

// Lets cache some selectors

var button1 = $('#button1'),

button2 = $('#button2'),

button3 = $('#button3'),

button4 = $('#button4'),

clear = $('#clear'),

holder = $('#holder');

// Case 1: Direct event handling

button1.on('click',function(){

log('Click');

});

// Case 2: Direct event handling of multiple events

button2.on('mouseenter mouseleave',function(){

log('In/Out');

});

// Case 3: Data passing

button3.on('click', Math.round(Math.random()*20), function(e){

// This will print the same number over and over again,

// as the random number above is generated only once:

log('Random number: ' + e.data);

});

// Case 4: Events with a namespace

button4.on('click.temp', function(e){

log('Temp event!');

});

button2.on('click.temp', function(e){

log('Temp event!');

});

// Case 5: Using event delegation

$('#holder').on('click', '#clear', function(){

log.clear();

});

// Case 6: Passing an event map

var t; // timer

clear.on({

'mousedown':function(){

t = new Date();

},

'mouseup':function(){

if(new Date() - t &gt; 1000){

// The button has been held pressed

// for more than a second. Turn off

// the temp events

$('button').off('.temp');

alert('The .temp events were cleared!');

}

}

});

技巧31:更快地阻止默认事件行为

<a href="http://google.com/" id="goToGoogle">Go To Google</a>

$('#goToGoogle').click(false);

技巧32:event.result链接多个事件处理程序

<button id="press">点击</button>

<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>

<script>

var press = $('#press');

press.on('click',function(){

return 'Hip';

});

// The second event listener has access

// to what was returned from the first

press.on('click',function(e){

console.log(e.result + ' Hop!');

});

</script>

技巧33:创建你自己习惯的事件

比如:你可以使用on()方法创建自己喜欢的事件名称,然后通过trigger来触发

<button id="button1">Jump</button> <button id="button2">Punch</button> <button id="button3">Click</button> <button id="clear" style="float: right;">Clear</button> <div id="eventDiv"></div>

<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>

<script>

var button1 = $('#button1'),

button2 = $('#button2'),

button3 = $('#button3'),

clear = $('#clear'),

div = $('#eventDiv');

div.on({

jump : function(){

alert('Jumped!');

},

punch : function(e,data){

alert('Punched '+data+'!');

},

click : function(){

alert('Simulated click!');

}

});

button1.click(function(){

div.trigger('jump');

});

button2.click(function(){

// Pass data along with the event

div.trigger('punch',['hard']);

});

button3.click(function(){

div.trigger('click');

});

clear.click(function(){

//some clear code

});

</script>

技巧34:在下载文件旁显示文件大小

<a href="001.html" class="fetchSize">First Trickshot</a> <br />

<a href="034.html" class="fetchSize">This Trickshot</a> <br />

<a href="assets/img/ball.png" class="fetchSize">Ball.png</a> <br />

// Loop all .fetchSize links

$('a.fetchSize').each(function(){

// Issue an AJAX HEAD request for each one

var link = this;

$.ajax({

type : 'HEAD',

url : link.href,

complete : function(xhr){

// Append the filesize to each

$(link).append(' (' + humanize(xhr.getResponseHeader('Content-Length')) + ')');

}

});

});

function humanize(size){

var units = ['bytes','KB','MB','GB','TB','PB'];

var ord = Math.floor( Math.log(size) / Math.log(1024) );

ord = Math.min( Math.max(0,ord), units.length-1);

var s = Math.round((size / Math.pow(1024,ord))*100)/100;

return s + ' ' + units[ord];

}

注意:这个例子如何我们直接使用浏览器是没法得到的,必须使用本地的web服务器打开运行才可以。

技巧35:使用延迟简化你的Ajax请求

// This is equivalent to passing a callback as the

// second argument (executed on success):

$.get('assets/misc/1.json').done(function(r){

log(r.message);

});

// Requesting a file that does not exist. This will trigger

// the failure response. To handle it, you would normally have to

// use the full $.ajax method and pass it as a failure callback,

// but with deferreds you can can simply use the fail method:

$.get('assets/misc/non-existing.json').fail(function(r){

log('Oops! The second ajax request was "' + r.statusText + '" (error ' + r.status + ')!');

});

技巧36:平行的运行多个Ajax请求

// The trick is in the $.when() function:

$.when($.get('assets/misc/1.json'), $.get('assets/misc/2.json')).then(function(r1, r2){

log(r1[0].message + " " + r2[0].message);

});

技巧37:通过jQuery获得ip:

$.get('http://jsonip.com/', function(r){ log(r.ip); });

// For older browsers, which don't support CORS

// $.getJSON('http://jsonip.com/?callback=?', function(r){ log(r.ip); });

技巧38:使用最简单的ajax请求

<p class="content"></p> <p class="content"></p>

var contentDivs = $('.content');

// Fetch the contents of a text file:

contentDivs.eq(0).load('1.txt');

// Fetch the contents of a HTML file, and display a specific element:

contentDivs.eq(1).load('1.html #header');

技巧39:序列化对象

<form action="">

First name: <input type="text" name="FirstName" value="Bill" /><br />

Last name: <input type="text" name="LastName" value="Gates" /><br />

</form>

// Turn all form fields into a URL friendly key/value string.

// This can be passed as argument of AJAX requests, or URLs.

$(document).ready(function(){

console.log($("form").serialize()); // FirstName=Bill&LastName=Gates

});

// You can also encode your own objects with the $.param method:

log($.param({'pet':'cat', 'name':'snowbell'}));

技巧40:使用jQuery上传二进制文件

// The file input field

var fileInput = $('input[type=file]'),

button = $('#upload');

button.on('click', function(){

// Access the files property, which holds

// an array with the selected files

var files = fileInput.prop('files');

// No file was chosen!

if(files.length == 0) {

alert('Please choose a file to upload!');

return false;

}

// Create a new FormData object

var fd = new FormData();

fd.append('file', files[0]);

// Upload the file to assets/php/upload.php. Open that file in a text

// editor to get a better idea of how it works.

$.ajax({

url: './assets/php/upload.php',

data: fd,

contentType:false, // This will make the browser use the multipart/formdata encoding, which is required for transferring binary data.

processData:false, // jQuery shouldn't do any processsing on the data - the browser will handle this when it sees we are passing a formdata object.

type:'POST',

success: function(m){

log(m);

}

});

});

技巧41:使用Facebook的图表

// Fetch the publicly accessible data on Tutorialzine's Page

var api = 'http://graph.facebook.com/Tutorialzine/?callback=?',

holder = $('#fbdata');

$.getJSON(api, function(r){

// This will always give the current picture

holder.append('<img src="http://graph.facebook.com/Tutorialzine/picture/?type=large">');

holder.append('<p>'+ r.about +'</p>')

holder.append('<a href="'+ r.website +'">'+ r.website +'</a>');

});

技巧42:获取天气信息

// Request weather data:

var api = 'http://openweathermap.org/data/2.1/find/name?q=paris,france&callback=?';

$.getJSON(api, function(r){

// This will always give the current picture

log(r.list[0].name + ', ' + r.list[0].sys.country);

log(r.list[0].main);

// Temperatures are in kelvin, subtract 273.15 to convert to Celsius,

});

技巧43: 获取你的最近的汤博乐(Tumblr)内容

<div id="post"></div>

// Define variables

var blog = 'minimaldesks.tumblr.com',

api = 'http://' + blog + '/api/read/json?callback=?',

post = $('#post');

$.getJSON(api, function(r){

log('Blog title: ' + r.tumblelog.title);

log('Description: ' + r.tumblelog.description);

// If this post has a photo, show it

if(r.posts[0]['photo-url-250']){

post.append('<img src="' + r.posts[0]['photo-url-250'] + '" />');

}

else{

log('Latest post: ' + r.posts[0]['regular-title']);

}

});

技巧44:通过IP地址获得地理位置

// Define variables

var ip = '119.75.218.70', // you can optionally put an ip address here

api = 'http://freegeoip.net/json/' + ip + '?callback=?';

$.getJSON(api, function(r){

console.log('How is the weather in ' + r.city + ', ' + r.country_name + '?');

}); //How is the weather in Beijing, China?

技巧45:使用YQL来爬网站

// Define variables

var query = 'select * from data.html.cssselect where url="http://www.chucknorrisfacts.com/chuck-norris-top-50-facts" and css=".field-content a"';

var yqlAPI = 'http://query.yahooapis.com/v1/public/yql?q=' + encodeURIComponent(query) + ' &format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=?';

$.getJSON(yqlAPI, function(r){

log('Chuck Norris Facts:');

$.each(r.query.results.results.a, function(){

log('----------');

log(this.content);

});

});

技巧46:使用全局的Ajax方法

// Create an indicator that would be shown whenever an AJAX request occurs:

var preloader = $('<div>',{ 'class':'preloader' }).appendTo('body');

var doc = $(document);

// Show the preloader whenever you are making an AJAX request:

doc.ajaxStart(function(){

preloader.fadeIn();

});

// Hide it when the ajax request finishes

doc.ajaxComplete(function(){

// Keep it visible for 0.8 seconds after the request completes

preloader.delay(800).fadeOut();

});

// It will show automatically every time you do an AJAX request:

$.get('assets/misc/1.json');

技巧47:爱上console吧

// The simple case. Use this instead of alert():

console.log('This is a console message!');

// It supports embedding of variables as well:

var a = 'morning', b = 'Miss';

console.log('Good %s %s! How are you feeling today?', a, b);

// Interactively browse the properties of a method (similar to console.log):

console.dir(window);

// Information message (in webkit it looks like console.log)

console.info('Everything is OK');

// Warning message

console.warn('Something may be wrong');

// Error message (will print a stack trace)

console.error('Ooops. That was bad.');

// Counting things

for(var i = 0; i<20; i++){

console.count('Counter Name');

}

// Starts a collapsable group of log messages

console.group("Preflight check");

console.info('Fuel is OK');

console.info('Temperature is normal');

console.error('Wings are missing');

console.groupEnd()

// Timing things

console.time('The million-dollar loop')

var dollars = 0;

for(var i=0;i<100000; i++){

dollars+=10;

}

console.timeEnd('The million-dollar loop');

// Profiling code (it will show up in your console's Profile tab)

console.profile('My app performance');

var arr = [];

$.each([0,1,2,3,4,5,6,7,8,9],function(){

arr.push(this+1);

});

console.profileEnd('My app performance');

技巧48:把代码转化为插件以提高重用率。

<input id="testInput" placeholder="YourName"/>

<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>

<script>

// Define the placeholder plugin

$.fn.placeholder = function(){

if ('placeholder' in document.createElement('input')){

// This browser already supports placeholders.

// Nothing to do here.

return this;

}

this.each(function(){

var input = $(this);

input.on('focus', function(){

if(input.val() == input.attr('placeholder')){

input.val('');

}

}).on('blur', function(){

if(input.val() == ''){

input.val(input.attr('placeholder'));

}

});

// Show the placeholder on load

input.trigger('blur');

});

return this;

};

// And here is how to use it:

$('#testInput').placeholder();

技巧49:使用匿名函数来产生一个独立的代码块

// Isolating a block of code:

(function($){

// Declare a variable. It will only be visible in this block.

var c = 1;

// Define a simple plugin

$.fn.count = function(){

// Increment and log the counter

log(c++);

return this;

};

})(jQuery);

// The c variable is only visible for the plugin and will keep

// its value between invocations:

$(document).count();

$('body').count().count();

技巧50:用extend融合对象

// Combine properties (useful in plugins).

// The defaults are passed as the first argument.

var supplied = { height: 400 };

var options = $.extend({

color : 'blue',

width : 200,

height : 150

}, supplied);

log('New options:', options);

// You can also pass more than one object

log('Three parents:', $.extend({a:2}, {b:3}, {c:4}) );

log('-------');

// Cloning objects.

// To clone an object, simply pass an empty one

// as the first argument

var original = {a:123, b:'#fff'};

var clone = $.extend({}, original);

log('Clone:', clone);

log('-------');

// Extending jQuery.

// You can define plugins with extend

$.extend($.fn, {

plugin1: function(){

log('Plugin 1');

return this;

},

plugin2: function(){

log('Plugin 2');

return this;

}

});

$('body').plugin1().plugin2();

log('-------');

// If you pass only one arguments to $.extend,

// it will add the properties to the jQuery object

$.extend({ dontDoThis : 123});

log($.dontDoThis);

log('-------');

// Deep cloning.

// If you have nested objects, you will have to

// pass one additional argument to extend:

var obj1 = { a: 1, b: 2, c: {d: 3} };

var obj2 = { c: {e: 4}, f:5};

// This won't work

// $.extend(obj1, obj2);

// This will

$.extend(true, obj1,obj2);

log('Deep clone:', obj1);