Как создать пустой, ненулевой объект jQuery, готовый для добавления? - PullRequest
47 голосов
/ 08 апреля 2011

Я хочу добавить html к пустому ненулевому объекту jQuery только в цикле, но он не работает, если я не создаю объект и не добавляю html-тег во время создания.Как я могу создать пустой объект jQuery и иметь возможность добавить html к нему позже?

//var $new = $().add("");  //can't use this object in the loop
//var $new = $([]);        //can't use this object in the loop
//var $new = $();        //can't use this object in the loop
//var $new = $("#nonexistingelement"); //can't use this object in the loop
var $new = $().add("<tr>");  //works but I don't want to add any html at this point. 

$.each(.....)
  {
    $new.append("<sometag>");

});

alert($new.html());  //should display some html

Добавление: http://jsfiddle.net/vfPNT/

Ответы [ 6 ]

76 голосов
/ 30 апреля 2011

Ваша проблема здесь в том, что нет «нулевых» объектов jQuery, к которым нельзя добавить, и «пустых», которые могут быть. Вы уже определили несколько способов создания пустого, и хотя их может быть больше, это не имеет значения - то, что вы пытаетесь сделать, просто не будет делать то, что вы ожидаете, независимо от того, как вы начинаете, потому что ...

... append() изменяет DOM, а не объект jQuery. А пустой объект jQuery не имеет DOM ! У Томалака была правильная идея , хотя, возможно, вы ее не поняли.

Я собираюсь сделать три замечания о jQuery, о которых вы, вероятно, уже знаете, но которые полезны для понимания оставшейся части этого ответа и, следовательно, могут принести пользу будущим читателям:

  1. Объект jQuery - это набор элементов DOM.
  2. Некоторые методы jQuery работают на множестве, а некоторые работают на узлах в множестве.
  3. Некоторые методы jQuery работают только на (или извлекают информацию только из) узла first , добавленного в набор.

Имея в виду эти три наблюдения, давайте рассмотрим ваш пример:

// 1. create an empty set somehow (doesn't matter how)
var $new = $();

// 2. iterate over something
$.each( ..., function( ... )
{
  // 3. construct a DOM fragment from HTML, and append it
  $new.append("<sometag>"); 
});

// 4. try to display HTML corresponding to the jQuery object
alert($new.html());  

В этом примере шаг # 3 не сможет сделать ничего полезного, потому что цель append() состоит в том, чтобы взять все заданные им элементы DOM и добавить их в качестве дочерних к каждому элементу DOM в наборе. , Поскольку $new - это пустой набор, нет элементов для добавления, и ... ничего не происходит. Шаг № 1 работает просто отлично, но, создав набор без каких-либо элементов DOM, вы настроили себя на неудачу, когда пытаетесь использовать существующие методы для изменения DOM! Ссылка Observation # 2 ... чтобы изменить набор, вам нужно вызвать метод, который на самом деле работает на наборе.

Хорошо, давайте предположим, что мы используем модификацию набора метод add() вместо:

  $new = $new.add("<sometag>");

Теперь у нас все хорошо, верно? Каждый проход по циклу создаст новый объект jQuery, состоящий из предыдущего набора + вновь созданный элемент. Ну что ж ...

... это только заставит шаг # 4 сделать что-то странное. Смотрите, html() - один из тех методов, которые я упомянул в Наблюдении № 3 - он работает только с первым элементом в наборе. Таким образом, вместо последовательности ("<sometag><sometag><sometag>...") вы получите только HTML-представление элемента, созданного при первом прохождении цикла ("<sometag>"). Кроме ... Вы даже не получите , что , потому что html() создает представление children элемента - так, что вы действительно закончится тем, что "" ...

Все это было просто большим разочарованием: вы начали работать с сетом (Шаг № 1), затем попытались работать с DOM (Шаг № 3) и закончили, пытаясь извлечь данные из один Элемент DOM (который не существовал) (и не имел бы никаких данных, если бы он существовал) (Шаг # 4).

Решение, которое вы, наконец, придумали , не страшно - вы, по сути, решаете добавить один корневой элемент в начало набора и полностью работать с этим фрагментом DOM пока вы не закончите добавлять новые элементы и не будете готовы работать с ними. Вы пропустили его в своем пересмотренном примере, но html() также будет работать, так как он просто выведет содержимое вашего корневого элемента.

Но просто для завершения приведу последний пример, который работает с set , начиная с пустого объекта jQuery:

var $new = $();
$.each( [1, 2, 3, 4], function(i, v)
{
  $new = $new.add("<div>");
});

alert($new.length == 4); // true

// alerts: <div></div><div></div><div></div><div></div>
alert($("<div>").append($new).html()); 
9 голосов
/ 21 февраля 2017

Фрагменты документов идеально подходят для этого;создает пустой объект, готовый для добавления.:)

$(document.createDocumentFragment())
2 голосов
/ 08 апреля 2011

Ваш объект $new является пустым селектором, поэтому append не имеет наборов для добавления.

add требуется для добавления узла DOM, а затем вы добавляете эти узлы DOM.Не думайте, что вы можете не начинать с .add.

1 голос
/ 03 сентября 2014

Я тестировал вышеупомянутое решение, но оно не работало для меня, оно всегда оставалось пустым объектом jQuery ...

, если кому-то интересно, вот мое решение:

var jQueryElements = [],
    $new;

$.each( [1, 2, 3, 4], function(i, v){
  jQueryElements = jQueryElements.push($('<div>').get(0));
});

$new = $(jQueryElements);
0 голосов
/ 29 августа 2018

, если вы не хотите получить уродливый тег:

if(!$new){
$new.append("</sometag>");
} else {
var $new = $("</sometag>");
0 голосов
/ 29 апреля 2011

Я не мог найти другой путь, поэтому я начал с <tr>.Удаление <tr> с сохранением содержимого не работало должным образом, и поэтому я разместил вопрос.Поэтому вместо этого я создал новый выбор jQuery, выделив все <sometag>'s which were inside the <tr> и выбросив $ new.

var $new = $().add("<tr>");  

$.each(.....)
  {
    $new.append("<sometag>");

});
$new.append("</tr>");
$newObject = $('sometagt', $new)
..... do more work using $newObject
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...