Подтвердить что ты не робот

Сохранить 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

4b9b3361

Ответ 1

У вас есть фундаментальное непонимание того, что

variableName = $("selector here");

делает. Он не "сохраняет селектор". Он запускает селектор, который вы указываете против текущих элементов в DOM, создает объект 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 не повлияло на объект jQuery, на который ссылается $divs.

$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

Если у вас есть объект jQuery, содержащий элемент DOM, и вы добавляете элементы-потомки к этому элементу DOM, то использование этого объекта jQuery с (скажем) .find будет видеть потомков. Это потому, что родительский элемент DOM уже существует в объекте jQuery. Например, добавив span к одному из div, который мы уже ссылаемся на наш объект jQuery:

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

Если бы мы использовали .find на $divs в тот момент, когда искали span, мы бы нашли его, потому что он был потомком одного из элементов, к которым у нас уже была ссылка.

Если вы хотите повторно запустить 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 2

Таким образом, "сохранение селектора", когда это необходимо, является вопросом хранения селекторной строки где-то, а не объектом jQuery.