Как работает функция pushStack jQuery?

У меня возникли проблемы с пониманием функции jQuery pushStack (документировано на http://api.jquery.com/pushStack/). Я попытался добавить список элементов в селектор в этом скрипте.

http://jsfiddle.net/johnhoffman/hTh8D/

JS:

$(function() {
   var listStuff = $("p");
   listStuff.pushStack($("div"));
   listStuff.css("color", "#f00");        
});​

HTML:

<p>foo</p>
<div>bar</div>​

Однако текст элемента div не является красным. Что значит нажимать элемент на стек jQuery?

Ответы

Ответ 1

.pushStack() создает новый объект jQuery, который наследует состояние от предыдущего объекта jQuery.

Это унаследованное состояние позволяет работать с такими методами, как .end() и .self(). В вашем конкретном примере кода вы не используете возвращаемое значение из .pushStack(), которое является новым объектом jQuery.

При работе с объектами jQuery важно знать, что большинство операций, которые изменяют объекты DOM в объекте jQuery, возвращают новый объект jQuery с изменением в нем, а не изменяют существующий объект jQuery. Именно эта конструктивная характеристика позволяет им поддерживать этот стек ранее измененных объектов jQuery.

В вашем случае я не думаю, что вам нужно использовать .pushStack() вообще, и вы, вероятно, можете просто использовать .add() (который также возвращает новый объект jQuery), но мне не совсем понятно, что вы Я пытаюсь это сделать, я не уверен, какой именно код рекомендуется.

Чтобы достичь конечного результата HTML, который вы указали в своем вопросе, вы можете сделать следующее:

$(function() {
   $("p").add("div").css("color", "#f00").appendTo(document.body);        
});​

Очевидно, вы можете изменить .appendTo() на все, что вы собираетесь делать с новыми объектами DOM.

В ваших комментариях вы еще раз спросили, когда можно использовать pushStack(). Я думаю, что основное использование - это методы jQuery, которые возвращают новый объект jQuery. В этом случае вы создаете новый список элементов, которые хотите в новом объекте jQuery, а затем вместо того, чтобы просто превращать это в обычный объект jQuery и возвращаете его, вы вызываете return this.pushStack(elems). Это создает новый объект jQuery и возвращает его, но также связывает этот новый объект с предыдущим объектом, чтобы специальные команды, такие как .end(), могли работать при использовании в цепочке.

Метод jQuery .add() является классическим примером. В псевдокоде он делает следующее:

add: function(selector, context) {
    // get the DOM elements that correspond to the new selector (the ones to be added)
    // get the DOM elements from the current jQuery object with this.get()
    // merge the two arrays of elements together into one array
    return this.pushStack(combinedElems);
}

Ответ 2

Вы не нажимаете объект, попробуйте следующее:

$(function() {
var listStuff = $("p");
listStuff.css("color", "#f00");        
this.pushStack( listStuff.get() );
});​