//檢測 window 中新增的對象 //first var oldMap = {}; for(var i in window) { oldMap[i] = 1; } //second for(var i in window) { if(oldMap[i]) continue; alert(i); } $()選擇器獲取到的既不是一個dom元素,也不是節點列表,而是一個新的對象 $() 不傳入任何參數會返回一個空的jquery對象 //google cdn獲取jquery <script type="text/javascript" src="http://www.google.com/jsapi"></script> <script> google.load("jquery",'1.4.2'); google.setOnLoadCallback(function(){alert('aa'+$)}); </script> //這種寫法更好 $ = [1,2]; jQuery(function($){ //自動傳入jQuery對象,即便外邊的$被覆蓋依然可使用$ alert($); }) //建立一個元素,同時給他添加一些屬性和方法 $("<input>", { type: "text", val: "Test", focusin: function() { $(this).addClass("active"); }, focusout: function() { $(this).removeClass("active"); } }).appendTo("form"); //獲取select標籤的值,當爲單選時爲一個數值,當爲多選時則會返回一個數組, //設置多選傳入數組 $("select").val([1,2,3]); $("select option:selected").each(function(){ alert(this.value); }) //綁定事件時傳入參數,很好的解決了閉包產生的問題 var message = 'Spoon!'; $('#foo').bind('click', {msg:message}, function(evt) { //訪問傳入參數的方式 alert(evt.data.msg); }); message = 'sjk'; 在事件處理函數內返回false就等價於執行事件對象上的.preventDefault()[ie:evt.returnValue=false;]和.stopPropagation()[ie:evt.cancelBubble=true;] jq綁定的事件只能用自身的方法來觸發,但js綁定的事件一樣能夠用jq來觸發 $("#song").click(function(evt){ alert(evt.originalEvent); //原始的事件對象 alert('click'); }) //事件綁定外邊的一個函數 function test(evt, msg){ alert(evt); alert(msg); alert(this.innerHTML); } document.getElementById('song').onclick = function(evt){ test.call(this, evt, 'ok'); //important }; // trigger傳入參數 $("#song").click( function (event, a, b) { // 一個普通的點擊事件時,a和b是undefined類型 // 若是用下面的語句觸發,那麼a指向"foo",而b指向"bar" alert(a+'\n'+b); } ).trigger("click", ["foo", "bar"]); live事件委託的原理 $(document).bind("click", function (e) { $(e.target).closest("li").toggleClass("hilight"); }); //新發現mouse事件 mouseenter / mouseleave jquery返回的對象很是相似數組,但並非繼承自數組 instanceof Array //會自動把數組的下標賦值到this下面 [].push.apply(this,ary); //jquery對象實現原理 function list(ary) { this.ary = ary; [].push.apply(this,ary); } list.prototype = { attr:function(){ for(var i=0;i<this.ary.lenght;i++){ this.ary[i][name] = value; } }, get:function(index){ if(index === undefined) return this.ary; else{ return this.ary[index]; } }, push:[].push, shift:[].shift } var l = new list([1,2,3]); l.push(4); l.push(5); console.dir(l); 下面的script標籤會等上面的script標籤中的內容所有加載完畢後才執行 xpath:比css選擇器更爲強大些 //改變某個函數的this上下文 function closure(fn,scope) { return function(){ fn.apply(scope, arguments); } } //調用一個對象上指定的方法 ps:貌似沒啥用? function invoke(obj, methodName) { return function(){ obj[methodName].apply(obj,arguments); }; } 都是返回一個通過包裝過的函數 //給函數增長屬性 function test(){ arguments.callee.guid = 1; } var fn = function(){ arguments.callee.guid = 1; } //fn();#必須執行後纔能有此屬性 alert(fn.guid); //一種變通的方式 給匿名 函數增長屬性 var fn = function(){ var anony = function(){ // your code } anony.guid = 1; return anony; } $.proxy(fn,scope)用法 $(function(){ function test(){ alert(this.html()); } var h = $(":header"); h.click($.proxy(test,h)) //改變this的值 alert(test.guid); //每一個函數賦值一個guid,當此函數通過閉包處理後返回的函數仍舊此函數的guid相同, 能夠用guid來判斷這兩個函數是相同的(通常狀況下咱們沒法比較兩個函數是否相同) }) w3c瀏覽器: addEventListener removeEventListener IE: attachEvent detachEvent //closest對於處理事件委託很是有用, 能夠實現 live 、delegate效果 $(document).bind("click", function (e) { $(e.target).closest("li").toggleClass("hilight"); }); 解決$命名空間衝突的問題 jQuery.noConflict(); jQuery(function($){ 傳入一個函數後,jquery會自動把他的全局命名空間($),傳入次函數的參數中 var len = $("ul li").length; console.log(len); }) 在引入jquery文件後馬上調用 //釋放$命名空間 jQuery.noConflict(); //釋放jQuery命名空間 jQuery.noConflict(true); 通常寫jquery代碼時能夠把$全局命名空間釋放掉,這樣就避免了和其餘插件的衝突 $能夠用局部的那個 //數據緩存 $("#song").data("title", 'title'); $("#song").data("age", 27); //不傳入參數則會返回一個js對象,並非dom對象 var obj = $("#song").data(); alert(obj.title); alert(obj.age); //能夠傳入obj,鍵值對 $("#song").data({name:12,age:27}); 源碼分析: //註冊命名空間 function test(){} var _nspool = {}; test.ns = function(name, value){ var names = name.split('.'); o = window; for(var i=0;i<names.length;i++) { if(!o[names[i]]) { o[names[i]] = {}; } o = o[names[i]]; _nspool[name] = o[names[i]]; o[names[i]] = value; } } test.ns('a.b.c', 123); console.dir(_nspool); //反註冊時只須要把 _nspool中的key值刪除 命名空間太長,可能會引發效率問題,能夠把他賦給一個值 [object Object] [基本類型 構造函數] alert({}.toString()); //數組上的toString方法被改寫了,因此咱們借用{}上的toString方法 判斷是不是一個數組 {}.toString.call([]); // [object Array] //插件機制 jQuery自己添加 jQuery.newMethod = function(){} jQuery.extend(obj); jQuery對象添加 jQuery.fn = jQuery.fn.init.prototype = function(){} jQuery.fn.extend(obj); //extend 函數默認複雜類型以引用傳遞 var o1 = {name:1}; var o2 = {age:{sex:{hel:1}}}; jQuery.extend(o1,o2); console.log(o1.age === o2.age); 代理函數:把新返回的函數的guid和原函數的guid設置成相同的,這樣解除綁定的時候傳入原函數便可 var obj = { name: "John", test: function() { alert( this.name ); $("#test").unbind("click", obj.test); } }; $("#song").click( jQuery.proxy( obj, "test" ) ); //如下代碼跟上面那句是等價的: ("#song").click( jQuery.proxy( obj.test, obj ) ); //能夠與單獨執行下面這句作個比較。 $("#song").click( obj.test ); 原生js實現jquery的proxy方法 //改變某個函數的內部this指針 function closure(fn, scope) { return function (){ fn.apply(scope, arguments); }; } //調用某個對象的某個函數,並將次對象做爲方法的做用域 function invoke(obj, methodName) { return function(){ obj.methodName(obj, arguments); }; } 函數綁定原理 var fns = [],conter = 0; //綁定 function addEvent(){ fn.guid = counter ++; fns[type] = fns[type] || {}; fns[type][fn.guid] = fn; o["on"+type] = function(){ //遍歷 fns } } //解除綁定 function delEvent(o, type, fn) { delete fns[type][fn.guid]; } jquery 插件 輪播器:slideview slinkySlider anythingSlider