由于工作主要用到Asp.net Mvc+Jquery,最近也看了一些Jquery的书籍,在此总结以备回顾。
已读书籍:《Jquery In Action》 主要讲了些Jquery语法以及API用法,感觉不错。
《Javascript the Missing Manual》 前半部分讲了下JS语法,感觉不错,后半部分讲了Jquery插件,没劲。
感觉读有些书还是不要太细了,浪费了很多时间,结果所获寥寥。我感觉自己比较适合泛读书然后实践加深理解。
Jquery
Javascript是一种脚本语言,不同于需编译的语言,运行时才被解释器解读。Jquery是基于JS的一个库。
Jquery filters即Jquery选择器,匹配语法类似CSS选择器,但也有一些进行了扩展(例如::not)。
Jquery选择器
快速回忆
$("p:even") | 匹配所有偶数的<p> |
$("tr:nth-child(1)") | 匹配每个<table>里第一行 |
$("body > div") | 匹配<body>的下一级所有<div> |
$("a[href$='pdf']") | 匹配所有PDF文件<a> |
$("body > div:has(a)") | 匹配<body>下一级所有包含<a>的<div> |
选择语法里的符号
> | 直系子元素 |
^ | 匹配元素对应属性开头字符串 例:a[href^='http://']匹配http://开头的<a> |
$ | 匹配元素对应属性尾部字符串 |
* | 匹配包含该字符串 例:a[href*='jquery.com']匹配包含jquery.com的<a> |
+ | 匹配紧跟在后面的一个同级元素 例:div+ul匹配每一个紧跟在<div>后并与它同级的<ul> |
~ | 匹配跟在后面的所有同级元素 例:div~ul匹配跟在<div>后面的所有同级<ul> |
选择器样板
* | ~所有元素 |
E | ~所有<E> |
E F | ~<E>的所有子节点<F> |
E>F | ~<E>的所有直系子<F> |
E+F | ~紧跟在<E>后的一个同级节点<F> |
E~F | ~跟在<E>后的所有同级节点<F> |
E.C | ~所有class为C的<E> |
E#I | ~Id为I的<E> |
E[A] | ~含有A属性的<E> |
E[A=V] | ~含有A属性值为V的<E> |
E[A^=V] | ~A属性值以V开头的<E> |
E[A$=V] | ~A属性值以V结尾的<E> |
E[A!=V] | ~不包含A属性或者A属性值不为V的<E> |
E[A*=V] | ~A属性值包含V的<E> |
位置选择
:first | ~符合条件的集合中第一个元素 例:li a:first匹配<li>里的第一个<a>(只有一个) |
:last | ~符合条件的集合中最后一个元素 |
:first-child | ~符合条件的第一个子元素 例: li a:first-child匹配每一个<li>里的第一个<a>(集合) |
:last-child | ~符合条件的最后一个子元素 |
:only-child | ~没有同级节点的元素 |
:nth-child(n) | ~符合条件的第n个子元素 注: first-child==nth-child(1) |
:nth-child(even|odd) | ~符合条件的偶数(奇数)位子元素 |
:nth-child(xn+y) | ~符合条件的xn+y位子元素 |
:even | ~偶数位元素 |
:odd | ~奇数位元素 |
:eq(n) | ~第n位元素 注: first==eq(0) |
:gt(n) | ~第n位及以后元素 |
:lt(n) | ~第n位及以前元素 注: first==lt(1) |
Note: 1.:first与:first-child有区别,前面的匹配一个元素,后面的匹配一个集合。详情
2.:eq是从0开始的,:nth-child是从1开始的
状态选择
:animated | ~正处于动画效果的元素 |
:button | ~button元素 包含input[type=submit],input[type=reset],input[type=button],button |
:checkbox | ~input[type=checkbox] |
:checked | ~处于选中状态的单选多选元素 |
:contains(food) | ~包含food文本的元素 |
:disabled | ~disabled的元素 |
:enabled | ~enabled的元素 |
:file | ~input[type=file] |
:has(selector) | ~包含selector元素的元素 |
:header | ~<h1>-<h6>所有标题元素 |
:hidden | ~hidden的元素(display:none) |
:image | ~input[type=image] |
:input | ~input,select,textarea,button |
:not(selector) | ~非selector的其它元素 |
:parent | ~有子元素(或者text)的元素 |
:password | ~input[type=password] |
:radio | ~input[type=radio] |
:reset | ~input[type=reset],button[type=reset] |
:selected | ~处于选中状态的<option> |
:submit | ~input[type=submit],button[type=submit] |
:text | ~input[type=text] |
:visible | ~visible的元素 |
Note:1.$("input[type='checkbox'][checked]")只能匹配初始状态为checked的元素。
$("input[type='checkbox']:checked")却可以匹配实时状态为checked的元素。
2.$(":not(img[src*='dog'])") 不仅匹配src属性包含dog的<img>而且匹配所有其它的标签
$("img:not([src*='dog'])") 只匹配src属性不包含dog的<img>
Jquery事件
on()方法将bind(),delegate(),live()方法已经合在了一块,用于事件绑定。详情
bind: function( types, data, fn ) {
return this.on( types, null, data, fn );
},
live: function( types, data, fn ) {
jQuery( this.context ).on( types, this.selector, data, fn );
return this;
},
delegate: function( selector, types, data, fn ) {
return this.on( types, selector, data, fn );
}
on(),live(),delegate()方法可以将事件绑定在动态生成的元素上,而bind(),单纯的click()等事件方法不具备此功能。
on()方法可以通过将事件绑定在目标元素的父元素上对该目标元素进行监听(事件冒泡机制),达到事件在动态元素上依然会触发的目的,
也可以直接绑定在目标元素上,但就不具备触发动态生成的元素的能力了。bind?live?delegate?还是on?–jquery事件绑定方法研究
Jquery扩展
jquery.fn=jquery.prototype
jQuery.fn = jQuery.prototype = {
// The current version of jQuery being used
jquery: version, constructor: jQuery, // Start with an empty selector
selector: "", // The default length of a jQuery object is 0
length: , toArray: function() {
return slice.call( this );
}, // Get the Nth element in the matched element set OR
// Get the whole matched element set as a clean array
get: function( num ) {
return num != null ? // Return a 'clean' array
( num < ? this[ num + this.length ] : this[ num ] ) : // Return just the object
slice.call( this );
}, // Take an array of elements and push it onto the stack
// (returning the new matched element set)
pushStack: function( elems ) { // Build a new jQuery matched element set
var ret = jQuery.merge( this.constructor(), elems ); // Add the old object onto the stack (as a reference)
ret.prevObject = this;
ret.context = this.context; // Return the newly-formed element set
return ret;
}, // Execute a callback for every element in the matched set.
// (You can seed the arguments with an array of args, but this is
// only used internally.)
each: function( callback, args ) {
return jQuery.each( this, callback, args );
}, map: function( callback ) {
return this.pushStack( jQuery.map(this, function( elem, i ) {
return callback.call( elem, i, elem );
}));
}, slice: function() {
return this.pushStack( slice.apply( this, arguments ) );
}, first: function() {
return this.eq( );
}, last: function() {
return this.eq( - );
}, eq: function( i ) {
var len = this.length,
j = +i + ( i < ? len : );
return this.pushStack( j >= && j < len ? [ this[j] ] : [] );
}, end: function() {
return this.prevObject || this.constructor(null);
}, // For internal use only.
// Behaves like an Array's method, not like a jQuery method.
push: push,
sort: arr.sort,
splice: arr.splice
};
How does Javascript.prototype work?
jquery.extend=jquery.fn.extend
jQuery.extend = jQuery.fn.extend = function() {
var options, name, src, copy, copyIsArray, clone,
target = arguments[] || {},
i = ,
length = arguments.length,
deep = false; // Handle a deep copy situation
if ( typeof target === "boolean" ) {
deep = target; // skip the boolean and the target
target = arguments[ i ] || {};
i++;
} // Handle case when target is a string or something (possible in deep copy)
if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
target = {};
} // extend jQuery itself if only one argument is passed
if ( i === length ) {
target = this;
i--;
} for ( ; i < length; i++ ) {
// Only deal with non-null/undefined values
if ( (options = arguments[ i ]) != null ) {
// Extend the base object
for ( name in options ) {
src = target[ name ];
copy = options[ name ]; // Prevent never-ending loop
if ( target === copy ) {
continue;
} // Recurse if we're merging plain objects or arrays
if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
if ( copyIsArray ) {
copyIsArray = false;
clone = src && jQuery.isArray(src) ? src : []; } else {
clone = src && jQuery.isPlainObject(src) ? src : {};
} // Never move original objects, clone them
target[ name ] = jQuery.extend( deep, clone, copy ); // Don't bring in undefined values
} else if ( copy !== undefined ) {
target[ name ] = copy;
}
}
}
} // Return the modified object
return target;
};
jquery.extend(object)为jquery类添加静态方法 例如$.trim()
jquery.fn.extend(object)为jquery对象添加方法 例如$("#aa").show()
js中的this与C#中的this有很大的区别:You must remember 'this'!
jquery源代码告诉我们:jquery.extend和jquery.fn.extend是同一个方法,只是会有this的区别。
简单的模拟:
var test = function(){};
test.extend = test.prototype.extend= function(){
var option = arguments[];
var target = this;
for(name in option)
{
target[name]=option[name];
}
return target;
}
test.prototype.extend({
test1:function(){alert("test1 prototype!") }
}); test.extend({test2:function(){ alert("test2 static!") } }); test.test2(); // alert test2 static! var cc = new test();
cc.test1(); // alert test1 prototype!
jquery插件
//step01 定义JQuery的作用域
(function ($) {
//step03-a 插件的默认值属性
var defaults = {
prevId: 'prevBtn',
prevText: 'Previous',
nextId: 'nextBtn',
nextText: 'Next'
//……
};
//step02 插件的扩展方法名称
$.fn.easySlider = function (options) {
//step03-b 合并用户自定义属性,默认属性
var options = $.extend(defaults, options);
}
})(jQuery);
总结
JQuery是一个非常棒的JS库,可以学习的东西很多。打算抽空看看JQuery源码