亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

jQuery構造函數init參數分析續

2019-11-20 12:29:56
字體:
來源:轉載
供稿:網友

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

// Handle HTML stringsif ( 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 checkmatch = [ null, selector, null ];} else {match = quickExpr.exec( selector );}

If里面先判斷第一個字符是“<”最后一個字符是“>”并且長度大于3就假設此時的selector是html簡單標簽 ,比如$(‘<div>')但是記住僅僅是假設”assume”比如$(‘<sdfadfadf>')這樣的也會走這里。然后把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 = /^(?:[^#<]*(<[/w/W]+>)[^>]*$|#([/w/-]*)$)/,

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

首先訪問http://bugs.jquery.com/然后搜索對應的值即可

quickExpr.exec( selector )執行的結果可以是一個數組,數組的第一個元素是匹配的元素,剩下的分別是分組匹配的元素,這個正則有兩個分組(<[/w/W]+>)[^>]和([/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 checkmatch = [ null, selector, null ];} else {match = quickExpr.exec( selector );} console.log(match); // [null, "<div>", null];

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

復制代碼 代碼如下:

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

還有一種比較特殊的情況$(‘<div>123')然后我們再看一下結果

復制代碼 代碼如下:

["<div>dewrwe", "<div>", undefined, index: 0, input: "<div>dewrwe"]

我們可以看到id總是在第三個元素而標簽值在第二個元素保存著,對于最后一種情況而言跟$(‘<div>')是沒有什么區別的因為生成dom元素時是不會處理第一個元素的。基于這個結果可以接著來分析下一個判斷了。

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

if ( match && (match[1] || !context) ) {     ...} else if ( !context || context.jquery ) {    ...} else {  ...}

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

1.標簽 

$(‘<div>')  $(‘<div>123')  $(‘<div>23213213</div>')...

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

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

// HANDLE: $(html) -> $(array)if ( match[1] ) {  ...// HANDLE: $("#id")}else{}

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

context = context instanceof jQuery ? context[0] : context;doc = ( context ? context.ownerDocument || context : document ); // If a single string is passed in and it's a single tag// just do a createElement and skip the restret = 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 ? 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構造函數里面聲明的目的是判斷單標簽  比如<div>這樣的

復制代碼 代碼如下:

// Match a standalone tag
rsingleTag = /^<(/w+)/s*//?>(?:<///1>)?$/,

然后把結果交給ret變量,基于ret的值又進行劃分按照單標簽和復雜標簽分開處理ret值存在那就是匹配到了單標簽然后再根據context是不是普通對象又分為兩種情況isPlainObject是檢測是不是普通對象的方法,如果是普通對象,就利用js原生方法createElement傳入標簽創建元素并放在一個數組里面,之所以這樣是為了以后跟jquery對象合并方便,然后把數組賦值給selector,后采用對象冒充的方法調用attr方法,這里attr居然有3個參數,而平常我們使用的api里面是兩個參數,其實jQuery中有很多類似的情況,同樣的方法有著對內對外兩個接口。第二個參數就是對象形式的上下文,因為attr可以像

復制代碼 代碼如下:

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

這給我們的其實就是我們以后可以$(‘<div>',{id:'div'})這樣寫了也是支持的。如果不是對象就直接創建元素不考慮屬性。還是把創建的元素放在數組里面。如果ret沒有值那就是復雜的標簽了比如$(‘<div>231</div>')這樣的這個時候原生的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 #6963if ( elem && elem.parentNode ) {// Handle the case where IE and Opera return items// by name instead of IDif ( elem.id !== match[2] ) {return rootjQuery.find( selector );}// Otherwise, we inject the element directly into the jQuery objectthis.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方法。

以上所述就是本文的全部內容了,希望大家能夠喜歡。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品免费看久久久香蕉| 麻豆成人在线看| 亚洲人成电影网站色xx| 日本精品久久中文字幕佐佐木| 欧美在线视频一区| 久久久久久久亚洲精品| 欧美性视频网站| 国产一区私人高清影院| 国产精品久久久久久av下载红粉| 欧美精品精品精品精品免费| 欧美老肥婆性猛交视频| 欧美在线视频播放| 亚洲成人精品久久| 亚洲天堂开心观看| 97成人精品视频在线观看| 亚洲天堂男人天堂| 亚洲午夜国产成人av电影男同| 最新中文字幕亚洲| 亚洲香蕉av在线一区二区三区| 高清视频欧美一级| 欧美电影免费在线观看| 成人自拍性视频| 伊人激情综合网| 欧美精品在线播放| 97在线视频精品| 欧美激情一区二区三级高清视频| 欧美成人精品一区| 日av在线播放中文不卡| 亚洲国产精品视频在线观看| 欧美精品在线免费| 国产精品久久久久久久7电影| 欧美性猛交xxxx偷拍洗澡| 日韩经典中文字幕| 久久久久久久久国产精品| 欧美日韩国产第一页| 欧美日韩美女在线| 欧美久久精品午夜青青大伊人| 国产一区二区在线免费视频| 久久福利视频网| 日本精品视频在线| 亚洲成人999| 欧美与黑人午夜性猛交久久久| 国产一区深夜福利| 亚洲电影中文字幕| 欧美激情视频一区二区三区不卡| 欧美高清视频在线| 亚洲大胆人体在线| 国产激情视频一区| 国产成人精品久久久| 久久精品99久久香蕉国产色戒| 97高清免费视频| 国产精品自产拍在线观| 中文字幕在线看视频国产欧美| 亚洲欧美国产精品专区久久| 欧美精品在线免费播放| 久久久久久久香蕉网| 国产精品白嫩美女在线观看| 欧美成人性色生活仑片| 亚洲欧美在线x视频| 国产日韩精品在线播放| 亚洲日本中文字幕| 91中文字幕在线观看| 国内久久久精品| 奇米成人av国产一区二区三区| 亚洲最新av在线| 欧美高清性猛交| 日韩av色在线| 在线激情影院一区| 欧美成人剧情片在线观看| 精品久久久一区| 国产97色在线| 欧美日韩免费在线| 精品激情国产视频| 亚洲成人激情在线| 欧美一区二区三区精品电影| 久久国产精品视频| 欧美在线性视频| 狠狠色狠狠色综合日日小说| 国产精品久久久久久久久粉嫩av| 91久久精品国产91性色| 日韩精品视频在线播放| 国产精品99久久99久久久二8| 精品动漫一区二区| 国产精品一区二区三区免费视频| 欧美国产高跟鞋裸体秀xxxhd| 国内精品400部情侣激情| 久久久久久香蕉网| 精品无人国产偷自产在线| 国产成人免费av电影| 91亚洲永久免费精品| 97国产在线视频| 丁香五六月婷婷久久激情| 欧美猛少妇色xxxxx| 高跟丝袜欧美一区| www.日韩欧美| 国产日韩专区在线| 成人黄色片网站| 亚洲国产精品高清久久久| 色婷婷综合久久久久中文字幕1| 欧美成人午夜激情视频| 欧美激情18p| 成人国内精品久久久久一区| 国产精品福利无圣光在线一区| 亚洲欧美国产精品专区久久| 久久久97精品| 精品国内产的精品视频在线观看| 欧美激情小视频| 亚洲美女www午夜| 日韩一区二区欧美| 色一情一乱一区二区| 亚洲精品中文字| 欧美日本精品在线| 久久97久久97精品免视看| 国产黑人绿帽在线第一区| 亚洲美女激情视频| 亚洲欧洲日产国码av系列天堂| 亚洲国产精品悠悠久久琪琪| 一区二区三区四区在线观看视频| 国产精品老牛影院在线观看| 亚洲美女黄色片| 伊人久久精品视频| 北条麻妃一区二区三区中文字幕| 国产精品久久久久久久久久东京| 久久艳片www.17c.com| 自拍偷拍免费精品| 色狠狠av一区二区三区香蕉蜜桃| 欧洲成人午夜免费大片| 欧美激情一区二区三区高清视频| 精品视频—区二区三区免费| 国产91av在线| 亚洲一区二区三| 欧美日韩国产123| 亚洲a∨日韩av高清在线观看| 欧美一级大胆视频| 久久精品国产2020观看福利| 欧美日韩加勒比精品一区| 亚洲欧洲第一视频| 国产香蕉一区二区三区在线视频| 孩xxxx性bbbb欧美| 在线成人激情黄色| 国产精品视频久久久| 日韩精品亚洲元码| 亚洲欧洲一区二区三区久久| 国产精品永久免费| 欧美性视频网站| 亚洲自拍偷拍福利| 国产精品夜间视频香蕉| 国产成人精品在线观看| www.日韩av.com| 91理论片午午论夜理片久久| 亚洲精品国产综合久久| 欧美日韩一区二区免费在线观看| 欧美激情精品久久久久久免费印度| 欧美成年人视频| 欧美性猛交丰臀xxxxx网站| 欧美激情网站在线观看| 日韩毛片中文字幕| 亚洲国产欧美一区二区三区久久| 亚洲成人网在线| 精品香蕉在线观看视频一| 欧美高清激情视频| 久久久精品视频在线观看| 日韩在线免费视频| 精品国产一区二区三区在线观看|