web-dev-qa-db-ja.com

変数にjqueryセレクターを保存する

次の例では、stored jQuery selectorは間違った値を返します。結果ではなくセレクターを保存する可能性はありますか?

Jsコード:

// storing the jQuery selectors
var
  $container = $( '.container' ),
  $element1  = $container.find( '.element' ),
  $element2  = $( '.element', $container ),
  $element3  = $( '.element' );

// append elements to the container
for( i=0; i<10; ++i ){
  $container.append( $(element_html) );  
}

// try the stored selectors -> returns 0
console.log( "1: " + $element1.length );
console.log( "2: " + $element2.length );
console.log( "3: " + $element3.length );

コンテナセレクタを使用して要素を検索する場合、なぜ機能するのですか?セレクタが要素ではなく、一致した要素にpointerを返すためです。

// this works
console.log( "1: " + $container.find( '.element' ).length );
console.log( "2: " + $( '.element', $container )  .length );
console.log( "3: " + $( '.element' )              .length );

jsFiddleデモンストレーション

33
TheGr8_Nik

あなたは何の根本的な誤解を持っています

_variableName = $("selector here");
_

します。 「セレクターを保存する」ことはありません。指定したセレクタをDOMのcurrent要素に対して実行し、jQueryオブジェクトを作成し、一致する要素をjQueryオブジェクトに配置して、そのjQueryオブジェクトへの参照を提供します。セレクターは保存されません(モジュロjQuery内部)。

与えられた:

_<body>
<div class="foo">x</div>
</body>
_

次に:

_var $divs = $("div.foo");
console.log($divs.length);        // 1
_

これを私たちに与えます:

$divs jQuery object pointing at one div in the DOM

次に、一致する別のdivを追加する場合:

_$('<div class="foo"></div>').appendTo(document.body);
_

_$divs_はまだ最初のものを指しているだけです。別の一致する要素をDOMに追加しても、_$divs_から参照されるjQueryオブジェクトには影響しません。

$divs jQuery object pointing to one div, but there are two in the DOM

その時点でクエリを再実行すると:

_$divs = $("div.foo");
_

...次に、

$divs jQuery object pointing at both divs in the DOM

DOM要素を含むjQueryオブジェクトがあり、そのDOM要素にdescendant要素を追加した場合、そのjQueryオブジェクトを(たとえば)_.find_と共に使用すると、子孫が表示されます。これは、親DOM要素がすでにjQueryオブジェクトに存在しているためです。たとえば、jQueryオブジェクトからalready参照するspansの1つにdivを追加します。

$divs jQuery object pointing at both divs in the DOM, one has a span now

その時点で_.find_で_$divs_を使用してspanを探していた場合、既に参照している要素の1つの子孫であるため、それを見つけます。 。

後でDOM検索を再実行して一致する要素を探す場合は、$()を再度使用します。これは上記では暗黙的ですが、明確にするために:

_var $divs = $("div.foo");
console.log($divs.length);        // 1
$('<div class="foo"></div>').appendTo(document.body);
console.log($divs.length);        // Still 1
$divs = $("div.foo");
console.log($divs.length);        // Now it's 2
_

したがって、「セレクターの格納」は、必要な場合、jQueryオブジェクトではなく、どこかにセレクター文字列を格納することです。

107
T.J. Crowder

受け入れられた答えは素晴らしいと思いますが、変数へのJQueryオブジェクトの割り当ては常に安全ではないと示唆するように解釈できます。そうすることは問題ありません-変数参照のDOMオブジェクトが、後のコードに影響する方法でアクセスする前に変更されない限り

[〜#〜] html [〜#〜]

<div id="banner-message">
    <p>Hello World</p>
    <button>Change view</button>
</div>

JavaScript

// find elements
var banner = $("#banner-message")
var button = $("button")

// handle click and add class
button.on("click", function(){
  banner.addClass("alt");
  banner.hide().html("New HTML").fadeIn(2000);
})

JsFiddle

1
Bob Ray