搜尋
首頁web前端js教程jQuery建構函式init參數分析續_jquery

如果selector是其他字串情況就比較多了比較複雜了

// Handle HTML strings
if ( typeof selector === "string" ) {...} 

開始分不同的狀況處理

// Are we dealing with HTML string or an ID?
if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
// Assume that strings that start and end with <> are HTML and skip the regex check
match = [ null, selector, null ];
} else {
match = quickExpr.exec( selector );
}

If裡面先判斷第一個字元是「」且長度大於3就假設此時的selector是html簡單標籤,例如$('

')但是記住僅僅是假設」assume」例如$('')這樣的也會走這裡。然後把match數組修改成[null,selector,null],這裡的match是在init函數裡面聲明的變量,主要是用來作為區分是參數類型的工具稍後在將可能情況列出,下面是源碼中宣告的四個變數
init: function( selector, context, rootjQuery ) {
var match, elem, ret, doc;

如果不滿足if的條件就會呼叫一個正規則去得到match的結果,quickExpr是jQuery建構函式裡面宣告的變數

// A simple way to check for HTML strings or ID strings
// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
quickExpr = /^(&#63;:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,

這個正規主要是為了區別html字串和id字串的,第二個註解中講到了為了避免基於location.hash的XSS 攻擊,於是在quickExpr 中增加了#(#9521)的意思是我們可以在jQuery官網找到相關解釋。

先造訪http://bugs.jquery.com/然後搜尋對應的值即可

quickExpr.exec( selector )執行的結果可以是一個數組,數組的第一個元素是匹配的元素,剩下的分別是分組匹配的元素,這個正則有兩個分組( )[^>]和([w-]*)一個是標籤一個是id值。最終會把結果交給match。以下就來分析下match的各種情況首先單標籤不用正規式是 [ null, selector, null ]的形式,以下在程式碼中證明:

<!doctype html>
<html>
  <head>
   <title></title>
    <script src='jquery-1.7.1.js'></script>
  </head>
  <body>
    <div id='div'></div> 
  </body>
  <script>
    $('<div>');
  </script>
</html>

在html裡面我們建立一個jQuery物件然後再init方法裡面輸出得到的match結果:

if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
// Assume that strings that start and end with <> are HTML and skip the regex check
match = [ null, selector, null ];
} else {
match = quickExpr.exec( selector );
}
 console.log(match); // [null, "<div>", null];

下面我們修改一下參數改為$(‘#div')然後再看一下結果

複製程式碼 程式碼如下:

["#div", undefined, "div", index: 0, input: "#div"]

還有一個比較特殊的情況$(‘

123')然後我們再看一下結果

複製程式碼 程式碼如下:

["
dewrwe", "
", undefined, index: 0, input: "
dewrwe"]

我們可以看到id總是在第三個元素而標籤值在第二個元素保存著,對於最後一種情況而言跟$('

')是沒有什麼區別的因為生成dom元素時是不會處理第一個元素的。基於這個結果可以接著來分析下一個判斷了。

接下來的會根據match的結果分為三種情況

if ( match && (match[1] || !context) ) {

     ...

} else if ( !context || context.jquery ) {

    ...

} else {

  ...

}

第一種情況滿足的條件是match一定要有值,match[1]就是第二個元素就是保存標籤的這個有值或不存在上下文,但是好像沒有id什麼事啊?其實不是的通過分析match的結果可以知道第二個元素沒有值肯定就是id選擇器得到的結果,而id是唯一的,不需要寫上下文(其實寫了上下文也會正常執行只不過會使用Sizzle而不是在這裡處理了跟body是一樣的)。好了第一個條件進來的狀況就是

1.標籤 

$(‘

')  $(‘
123')  $(‘
23213213
')...

2.沒有上下文的id  $(‘#div')

第一個條件內部又進行了細分:

// HANDLE: $(html) -> $(array)
if ( match[1] ) {

  ...

// HANDLE: $("#id")

}else{

}

很顯然if是處理標籤的else是處理id的,先來看看是怎麼處理標籤的吧

context = context instanceof jQuery &#63; context[0] : context;
doc = ( context &#63; context.ownerDocument || context : document );
 
// If a single string is passed in and it's a single tag
// just do a createElement and skip the rest
ret = rsingleTag.exec( selector );
 
if ( ret ) {
if ( jQuery.isPlainObject( context ) ) {
selector = [ document.createElement( ret[1] ) ];
jQuery.fn.attr.call( selector, context, true );
 
} else {
selector = [ doc.createElement( ret[1] ) ];
}
 
} else {
ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
selector = ( ret.cacheable &#63; jQuery.clone(ret.fragment) : ret.fragment ).childNodes;
}
 
return jQuery.merge( this, selector);

先修正一下context的值,如果是jQuery物件就把他變成dom元素就是使用下標的方法這個原理之前說過了,然後有處理了doc變量,如果context不存在就把document賦值給doc如果存在且有ownerDocument屬性那就是dom元素了這個值還是document如果不是dom元素比如普通的js物件的話那就把這個物件賦值給doc變數。緊接著對selector又進行了一個正規判斷,這個正則也是在jQuery構造函數裡面宣告的目的是判斷單標籤  例如

這樣的

複製程式碼 程式碼如下:

// Match a standalone tag
rsingleTag = /^(?:)?$/,

然后把结果交给ret变量,基于ret的值又进行划分按照单标签和复杂标签分开处理ret值存在那就是匹配到了单标签然后再根据context是不是普通对象又分为两种情况isPlainObject是检测是不是普通对象的方法,如果是普通对象,就利用js原生方法createElement传入标签创建元素并放在一个数组里面,之所以这样是为了以后跟jquery对象合并方便,然后把数组赋值给selector,后采用对象冒充的方法调用attr方法,这里attr居然有3个参数,而平常我们使用的api里面是两个参数,其实jQuery中有很多类似的情况,同样的方法有着对内对外两个接口。第二个参数就是对象形式的上下文,因为attr可以像

复制代码 代码如下:

$("img").attr({ src: "test.jpg", alt: "Test Image" });

这给我们的其实就是我们以后可以$(‘

',{id:'div'})这样写了也是支持的。如果不是对象就直接创建元素不考虑属性。还是把创建的元素放在数组里面。如果ret没有值那就是复杂的标签了比如$(‘
231
')这样的这个时候原生的js就搞不定啦需要调取另外一个方法jQuery.buildFragment来处理,这个方法实现以后在学习吧,总之最后都会创建dom元素。最后返回合并后的结果

复制代码 代码如下:

return jQuery.merge( this, selector );

不像之前的return this这里是返回merge执行后的结果其实他的任务就是把放在数组里面的创建好的的dom元素合并到jquery元素中去,最终变成{0:div,length:1...}这样的对象形式。这样的话简标签情况就处理完毕。

然后else里面处理的是id的情况

elem = document.getElementById( match[2] );
// Check parentNode to catch when Blackberry 4.6 returns
// nodes that are no longer in the document #6963
if ( elem && elem.parentNode ) {
// Handle the case where IE and Opera return items
// by name instead of ID
if ( elem.id !== match[2] ) {
return rootjQuery.find( selector );
}
// Otherwise, we inject the element directly into the jQuery object
this.length = 1;
this[0] = elem;
}
this.context = document;
this.selector = selector;
return this;

很简单直接调用原生js的id选择器但是有一些系统会出现bug

注释说的很清楚黑莓系统,就是元素已经不存在了但是依然能够匹配得到所以再加上父节点,不存在的元素肯定没有父节点的。还有一种情况就是ie和opera浏览器会出现按name值匹配的情况所以在做了一个判断

if ( elem.id !== match[2] ) {

如果真的不幸出现了那就不能使用原生方法而是用find方法也就是使用sizzle引擎了,在大多数正常情况下就直接将获取到的元素放到this里面就可以啦然后修改下context的值。Ok终于把第一个大分支分析完了。然后再看根据match的第二个分支

 else if ( !context || context.jquery ) {
  return ( context || rootjQuery ).find( selector );
}

这里是如果没有上下文或者上下文是jquery对象的时候这个比较简单就是直接用find方法了rootjQuery 就是$(document)

最后字符串的情况上面都不属于的话

复制代码 代码如下:

return this.constructor( context ).find( selector );

This.constructor就是jQuery其实还是使用find方法。

以上所述就是本文的全部内容了,希望大家能够喜欢。

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
jquery实现多少秒后隐藏图片jquery实现多少秒后隐藏图片Apr 20, 2022 pm 05:33 PM

实现方法:1、用“$("img").delay(毫秒数).fadeOut()”语句,delay()设置延迟秒数;2、用“setTimeout(function(){ $("img").hide(); },毫秒值);”语句,通过定时器来延迟。

jquery怎么修改min-height样式jquery怎么修改min-height样式Apr 20, 2022 pm 12:19 PM

修改方法:1、用css()设置新样式,语法“$(元素).css("min-height","新值")”;2、用attr(),通过设置style属性来添加新样式,语法“$(元素).attr("style","min-height:新值")”。

axios与jquery的区别是什么axios与jquery的区别是什么Apr 20, 2022 pm 06:18 PM

区别:1、axios是一个异步请求框架,用于封装底层的XMLHttpRequest,而jquery是一个JavaScript库,只是顺便封装了dom操作;2、axios是基于承诺对象的,可以用承诺对象中的方法,而jquery不基于承诺对象。

jquery怎么在body中增加元素jquery怎么在body中增加元素Apr 22, 2022 am 11:13 AM

增加元素的方法:1、用append(),语法“$("body").append(新元素)”,可向body内部的末尾处增加元素;2、用prepend(),语法“$("body").prepend(新元素)”,可向body内部的开始处增加元素。

jquery怎么删除div内所有子元素jquery怎么删除div内所有子元素Apr 21, 2022 pm 07:08 PM

删除方法:1、用empty(),语法“$("div").empty();”,可删除所有子节点和内容;2、用children()和remove(),语法“$("div").children().remove();”,只删除子元素,不删除内容。

jquery中apply()方法怎么用jquery中apply()方法怎么用Apr 24, 2022 pm 05:35 PM

在jquery中,apply()方法用于改变this指向,使用另一个对象替换当前对象,是应用某一对象的一个方法,语法为“apply(thisobj,[argarray])”;参数argarray表示的是以数组的形式进行传递。

jquery on()有几个参数jquery on()有几个参数Apr 21, 2022 am 11:29 AM

on()方法有4个参数:1、第一个参数不可省略,规定要从被选元素添加的一个或多个事件或命名空间;2、第二个参数可省略,规定元素的事件处理程序;3、第三个参数可省略,规定传递到函数的额外数据;4、第四个参数可省略,规定当事件发生时运行的函数。

jquery怎么去掉只读属性jquery怎么去掉只读属性Apr 20, 2022 pm 07:55 PM

去掉方法:1、用“$(selector).removeAttr("readonly")”语句删除readonly属性;2、用“$(selector).attr("readonly",false)”将readonly属性的值设置为false。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前By尊渡假赌尊渡假赌尊渡假赌
倉庫:如何復興隊友
4 週前By尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)