日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

读jQuery源码释疑笔记

發(fā)布時(shí)間:2023/12/20 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 读jQuery源码释疑笔记 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本釋疑筆記是針對(duì)自己在看源碼的過(guò)程中遇到的一些問(wèn)題的解答,對(duì)大眾可能不具有參考性,不過(guò)可以看看有沒(méi)有你也不懂得地方,相互學(xué)習(xí),相互進(jìn)步。

?1、each的用法

之前對(duì)each的用法一直迷迷糊糊,這次終于懂了。

源碼:

each: function( obj, callback, args ) {var value,i = 0,length = obj.length,isArray = isArraylike( obj );if ( args ) {if ( isArray ) {for ( ; i < length; i++ ) {value = callback.apply( obj[ i ], args );if ( value === false ) {break;}}} else {for ( i in obj ) {value = callback.apply( obj[ i ], args );if ( value === false ) {break;}}}// A special, fast, case for the most common use of each} else {if ( isArray ) {for ( ; i < length; i++ ) {value = callback.call( obj[ i ], i, obj[ i ] );if ( value === false ) {break;}}} else {for ( i in obj ) {value = callback.call( obj[ i ], i, obj[ i ] );if ( value === false ) {break;}}}}return obj;}, View Code

each函數(shù)可以傳進(jìn)去三個(gè)參數(shù),第一個(gè)是對(duì)象或者數(shù)組,第二個(gè)是回調(diào)函數(shù),第三個(gè)同樣是數(shù)組或者對(duì)象

實(shí)例:

var t={name:"t",age:"t1"};var tt=[1,2,3];$.each(t,function(j){console.log(j); //1; 1 每次迭代輸出一個(gè)值 },tt)$.each(tt,function(j){console.log(j); //1; 1},t)//undefinded ;undefined ;undefined 每次迭代輸出一個(gè)值 $.each(t,function(j){console.log(j); //name; age })$.each(t,function(i,j){console.log(i+" "+j);//name t; age t1 })$.each(tt,function(i,j){console.log(i+" "+j);//0 1; 1 2; 2 3;})

?jQuery中經(jīng)常采用each的方式為來(lái)創(chuàng)建函數(shù)。

?

依次迭代數(shù)組中的元素,為其綁定方法,省力且簡(jiǎn)單易懂。

?

2、一個(gè)等式

var name="t"; var getByName = typeof name === "string"; // name必須是字符串 console.log(getByName); //true console.log(name); //t

//類似的還出現(xiàn)在access函數(shù)中。
bulk = key == null;

?3、exec() 方法用于檢索字符串中的正則表達(dá)式的匹配。

exec() 方法用于檢索字符串中的正則表達(dá)式的匹配。返回一個(gè)數(shù)組,其中存放匹配的結(jié)果。如果未找到匹配,則返回值為 null。

如果 exec() 找到了匹配的文本,則返回一個(gè)結(jié)果數(shù)組。否則,返回 null。此數(shù)組的第 0 個(gè)元素是與正則表達(dá)式相匹配的文本,第 1 個(gè)元素是與 RegExpObject 的第 1 個(gè)子表達(dá)式相匹配的文本(如果有的話),第 2 個(gè)元素是與 RegExpObject 的第 2 個(gè)子表達(dá)式相匹配的文本(如果有的話),以此類推。除了數(shù)組元素和 length 屬性之外,exec() 方法還返回兩個(gè)屬性。index 屬性聲明的是匹配文本的第一個(gè)字符的位置。input 屬性則存放的是被檢索的字符串 string。我們可以看得出,在調(diào)用非全局的 RegExp 對(duì)象的 exec() 方法時(shí),返回的數(shù)組與調(diào)用方法 String.match() 返回的數(shù)組是相同的。

但是,當(dāng) RegExpObject 是一個(gè)全局正則表達(dá)式時(shí),exec() 的行為就稍微復(fù)雜一些。它會(huì)在 RegExpObject 的 lastIndex 屬性指定的字符處開(kāi)始檢索字符串 string。當(dāng) exec() 找到了與表達(dá)式相匹配的文本時(shí),在匹配后,它將把 RegExpObject 的 lastIndex 屬性設(shè)置為匹配文本的最后一個(gè)字符的下一個(gè)位置。這就是說(shuō),您可以通過(guò)反復(fù)調(diào)用 exec() 方法來(lái)遍歷字符串中的所有匹配文本。當(dāng) exec() 再也找不到匹配的文本時(shí),它將返回 null,并把 lastIndex 屬性重置為 0。

var str = "Visit W3School"; var patt = new RegExp("W3School","g"); var result;while ((result = patt.exec(str)) != null) {document.write(result);document.write("<br />");document.write(patt.lastIndex);}輸出: W3School 14

rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/;
var str = ' <div id=top></div>';
var match = rquickExpr.exec(str);
console.log(match)
//[" <div id=top></div>", "<div id=top></div>", undefined, index: 0, input: " <div id=top></div>"]

var str = '#test';
var match = rquickExpr.exec(str);
console.log(match[1])//undefined

rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)/,\1\1replace時(shí)/,這里后面\1的用法。\1類似replace時(shí)候用的′1',可以匹配第一個(gè)子匹配

?之所以會(huì)有undefined,是因?yàn)樽詈蟮哪莻€(gè)#不匹配,也就是沒(méi)有找到。找的順序是先從第一個(gè)小括號(hào)開(kāi)始找起,然后再開(kāi)始第二個(gè)小括號(hào),哪怕第二個(gè)小括號(hào)在第一個(gè)小括號(hào)里面。

match數(shù)組從0開(kāi)始標(biāo)記,match[0],代表第一個(gè)匹配的內(nèi)容。也就是index的值,表示第一次匹配的地方。

4、ownerDocument和 documentElement的區(qū)別

  • ownerDocument是Node對(duì)象的一個(gè)屬性,返回的是某個(gè)元素的根節(jié)點(diǎn)文檔對(duì)象:即document對(duì)象
  • documentElement是Document對(duì)象的屬性,返回的是文檔根節(jié)點(diǎn)
  • 對(duì)于HTML文檔來(lái)說(shuō),documentElement是<html>標(biāo)簽對(duì)應(yīng)的Element對(duì)象,ownerDocument是document對(duì)象
<div id="one"></div><div></div><script >var dom=document.getElementById("one");console.log($("div").ownerDocument);//undefinedconsole.log(document.ownerDocument);//nullconsole.log(document.documentElement.ownerDocument);//document對(duì)象console.log(document.body.ownerDocument);//document對(duì)象console.log(dom.ownerDocument);//document對(duì)象console.log(dom.nodeType);//1console.log(window.document.nodeType);//9console.log(window.document);//document對(duì)象console.log(document.body.ownerDocument.defaultView);//window對(duì)象console.log(dom.ownerDocument.defaultView);//window對(duì)象console.log(dom.ownerDocument.documentElement);//<html><head><body>....是標(biāo)簽</script>

?

5、jQuery.parseHTML

使用原生的DOM元素的創(chuàng)建函數(shù)將字符串轉(zhuǎn)換為一組DOM元素,然后,可以插入到文檔中。

str = "hello, <b>my name is</b> jQuery.", html = $.parseHTML( str ),

?6、strundefined = typeof undefined

將undefined類型轉(zhuǎn)化為字符串,用于判斷

strundefined = typeof undefined,console.log(strundefined+" "+$.type(strundefined));//undeined string

?7、節(jié)點(diǎn)關(guān)系

其實(shí)不難發(fā)現(xiàn),一個(gè)節(jié)點(diǎn)跟另一個(gè)節(jié)點(diǎn)有以下幾種關(guān)系:祖宗和后代,父親和兒子,臨近兄弟,普通兄弟。

在CSS選擇器里邊分別是用:空格;>;+;~

(其實(shí)還有一種關(guān)系:div.aaron,中間沒(méi)有空格表示了選取一個(gè)class為aaron的div節(jié)點(diǎn))爺爺grandfather與孫子child1屬于祖宗與后代關(guān)系(空格表達(dá))

  • 父親father與兒子child1屬于父子關(guān)系,也算是祖先與后代關(guān)系(>表達(dá))
  • 哥哥child1與弟弟child2屬于臨近兄弟關(guān)系(+表達(dá))
  • 哥哥child1與弟弟child2,弟弟child3都屬于普通兄弟關(guān)系(~表達(dá))

?

8、value.match( core_rnotwhite )

閱讀源碼的過(guò)程中,經(jīng)常會(huì)遇到

classNames = value.match( core_rnotwhite ) || [];

//core_rnotwhite = /\S+/g ,匹配任意不是空白符的字符串

match返回的是一個(gè)數(shù)組,因此如果不滿足的話,就返回空數(shù)組

等類似的表達(dá),其實(shí)就是將 value 用空格分開(kāi)成一個(gè)數(shù)組,相當(dāng)于 classes = (value || "").split("/\s+/")

?

9、函數(shù)的傳入?yún)?shù)為空和“”之間的區(qū)別

?

  $("#one").removeClass("");console.log( $('#one').attr('class') );//1 huanshen huansky$("#one").removeClass();console.log( $('#one').attr('class') );// var t=null ? 1 : 0;console.log(t);//0var t=" " ? 1 : 0;console.log(t);//1var t="" ? 1 : 0;console.log(t);//0function sum(){console.log(arguments.length);//1 };sum("");

?

傳入?yún)?shù)為“”的時(shí)候,arguments.length的值等于1,其實(shí)就是有一個(gè)參數(shù)傳進(jìn)去,哪怕是“”,但是不傳參數(shù)的時(shí)候,arguments.length=0;

removeClass不傳入?yún)?shù)的時(shí)候,就將所有的class都移除

?10、on,bind,delegate,live

其實(shí).bind(), .live(), .delegate()都是通過(guò).on()來(lái)實(shí)現(xiàn)的,.unbind(), .die(), .undelegate(),也是一樣的都是通過(guò).off()來(lái)實(shí)現(xiàn)的。提供了一種統(tǒng)一綁定事件的方法

.delegate()就是事件委托

$('#element).delegate('a', 'click', function() { alert("!!!") });

?.bind ? ? ??$('#foo').bind('click',function(){ })

.live(),將委托的事件處理程序附加到一個(gè)頁(yè)面的document元素,從而簡(jiǎn)化了在頁(yè)面上動(dòng)態(tài)添加的內(nèi)容上事件處理的使用。現(xiàn)在已經(jīng)被廢棄了,?

$('a').live('click', function() { alert("!!!") });

?one,只觸發(fā)一次

one: function( types, selector, data, fn ) {return this.on( types, selector, data, fn, 1 ); },

直接采用on的委托事件

$('.ul').on('click', 'a', function(e){  alert('click event');});

.bind()方法用于直接附加一個(gè)事件處理程序到元素上。

總結(jié):

在下列情況下,應(yīng)該使用.delegate(),而不能使用.bind():

  • 為DOM中的很多元素綁定相同事件;
  • 為DOM中尚不存在的元素綁定事件;

用.bind()的代價(jià)是非常大的,它會(huì)把相同的一個(gè)事件處理程序hook到所有匹配的DOM元素上
.delegate()會(huì)提供很好的方法來(lái)提高效率,同時(shí)我們可以添加一事件處理方法到動(dòng)態(tài)添加的元素上
我們可以用.on()來(lái)代替上述的3種方法

不足點(diǎn)也是有的:

  • 并非所有的事件都能冒泡,如load, change, submit, focus, blur
  • 加大管理復(fù)雜。
  • 不好模擬用戶觸發(fā)事件

如何取舍就看項(xiàng)目實(shí)際中運(yùn)用了。

?

總結(jié)

以上是生活随笔為你收集整理的读jQuery源码释疑笔记的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。