ホームページ > ウェブフロントエンド > jsチュートリアル > jQuery コンストラクターの初期パラメーターの分析 continue_jquery

jQuery コンストラクターの初期パラメーターの分析 continue_jquery

WBOY
リリース: 2016-05-16 15:59:26
オリジナル
1352 人が閲覧しました

セレクターが別の文字列の場合、状況はさらに複雑になります

// 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 );
}
ログイン後にコピー

最初の文字が「<」で最後の文字が「>」で長さが 3 より大きいと判断された場合、このときのセレクタは単純な HTML タグであると見なされます。 $('

') のようになりますが、$('') のような "assume" がここに入るということを覚えておいてください。次に、match 配列を [null, selector, null] に変更します。ここでの match は、主にパラメータの型を区別するためのツールとして使用されます。ソースコード。宣言された 4 つの変数

init: function( selector, context, rootjQuery ) {
var match, elem, ret, doc;

ログイン後にコピー

if 条件が満たされない場合、正規表現が呼び出されて一致結果が取得されます。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 文字列を区別するためのものです。2 番目のコメントでは、location.hash に基づく XSS 攻撃を回避するために、quickExpr に # (#9521) が追加されると述べています。 jQueryの公式サイトにあります。

まず http://bugs.jquery.com/ にアクセスし、対応する値を検索します

quickExpr.exec(selector) の実行結果は配列になります。配列の最初の要素は一致する要素であり、残りの要素はグループ化された一致する要素です。この正規表現には 2 つのグループ (<[wW]) があります。 >)[^>] と ([w-]*) はラベルと ID 値です。結果は最終的に一致するように与えられます。さまざまな一致状況を分析してみましょう。まず、正規表現を持たない単一ラベルは [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 メソッドで一致結果を出力します。


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"、未定義、"div"、インデックス: 0、入力: "#div"]

特殊なケース $(‘
123') もありますので、結果を見てみましょう

コードをコピーします コードは次のとおりです:
["
dewrwe", "
"、未定義、インデックス: 0、入力: "
dewrwe"]

最後のケースでは、ID が常に 3 番目の要素にあり、タグ値が 2 番目の要素に保存されていることがわかります。これは、使用時に $('
') が生成されるためです。 dom 要素の場合、最初の要素は処理されません。この結果に基づいて、次の判断の分析に進むことができます。

試合結果から以下の3つの状況に分けてご紹介します


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

     ...

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

    ...

} else {

  ...

}

ログイン後にコピー
最初のケースで満たされる条件は、match に値が必要であるということです。Match[1] は、2 番目の要素が値を持っているか、コンテキストを持たないことを意味します。 IDが無いようですが、どうしたのですか?実際にはそうではなく、一致結果を分析すると、値のない 2 番目の要素は ID セレクターによって取得された結果である必要があり、ID は一意であり、コンテキストを記述する必要がないことがわかります。 (実際、コンテキストが書かれていれば通常通り実行されますが、代わりに Sizzle が使用されます。ここでは本文と同じように処理されません)。さて、最初の条件は

です

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 要素に変換します。その後、context が存在しない場合は doc 変数が処理されます。 document 値を doc に割り当てます。それが存在し、ownerDocument 属性を持っている場合、この値は dom 要素です (通常の js オブジェクトなど)。このオブジェクトを doc に割り当てます。変数。その直後、別の通常の判定がセレクターに対して実行されました。この通常のルールは、

などの単一タグを判定する目的で jQuery コンストラクター内でも宣言されました。

コードをコピー コードは次のとおりです:

// 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" });

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

',{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方法。

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

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート