jquery .html () против .append ()


248

Допустим, у меня есть пустой div:

<div id='myDiv'></div>

Это:

$('#myDiv').html("<div id='mySecondDiv'></div>");

Такой же как:

var mySecondDiv=$("<div id='mySecondDiv'></div>");
$('#myDiv').append(mySecondDiv);

21
нет, второй не имеет идентификатора, поэтому тот же текст не будет выводиться.
Мэтт Эллен

.html намного быстрее после первого запуска. Это может занять секунду или около того, когда вы запускаете его в первый раз.
Sukhjit Dhot

Ответы:


316

Всякий раз, когда вы передаете строку HTML любому из методов jQuery, вот что происходит:

Временный элемент создан, назовем его х. x innerHTMLустановлен на строку HTML, которую вы передали. Затем jQuery перенесет каждый из созданных узлов (то есть х childNodes) во вновь созданный фрагмент документа, который затем будет кешироваться в следующий раз. Затем он вернет фрагмент childNodesкак свежую коллекцию DOM.

Обратите внимание, что на самом деле все намного сложнее, так как jQuery выполняет несколько кросс-браузерных проверок и различные другие оптимизации. Например, если вы перейдете просто <div></div>к jQuery(), JQuery будет использовать ярлык и просто сделать document.createElement('div').

РЕДАКТИРОВАТЬ : Чтобы увидеть огромное количество проверок, которые выполняет jQuery, посмотрите здесь , здесь и здесь .


innerHTMLкак правило, более быстрый подход, хотя не позволяйте этому управлять тем, что вы делаете все время. Подход jQuery не так прост, как element.innerHTML = ...- как я уже упоминал, происходит множество проверок и оптимизаций.


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

jQuery(Array(101).join('<div></div>'));

Есть также проблемы читабельности и обслуживания, которые необходимо учитывать.

Это:

$('<div id="' + someID + '" class="foobar">' + content + '</div>');

... намного сложнее поддерживать, чем это:

$('<div/>', {
    id: someID,
    className: 'foobar',
    html: content
});

5
JQuery (Array (101) .join ( '<DIV> </ DIV>')); <- почему 101 вместо 100?
Таконе

2
Просто хотел добавить точку данных. Провести некоторое тестирование производительности в приложении, которое загружает большую (10K +) партию <li> в <ul> и видит увеличение времени рендеринга (не загрузки) с ~ 12 с -> .25 с переключением .append ( iantListHTMLAsASingleString) в .html (iantListHTMLAsASingleString). Если вы уже выполняете трюк 'join' или создаете большую html-строку в своем списке, в этих двух методах определенно есть результат diff.
omnisis

9
@tacone Потому что соединение "клей" применяется между элементами массива. 101будет иметь 100 клеев применяются, так же , как присоединение 3 элемента будет иметь 2 клеев: EL-glue-EL-glue-EL. В примере Джеймса элементы массива «пустые», поэтому объединение N пустых элементов приводит к N-1 последовательным склейкам.
Фабрисио Мате

5
Для тех, кто интересуется ссылкой на синтаксис jquery, использованный выше, и на то, что разрешено, смотрите api.jquery.com/jquery/#jQuery-html-attributes .
Таддеус Альберс

1
Существует большая разница в том, что он теряет все данные, которые были прикреплены к доменам.
Адриан Варфоломей

68

Они не одинаковы. Первый заменяет HTML, не создавая сначала другой объект jQuery. Второй создает дополнительную оболочку jQuery для второго элемента div, а затем добавляет его к первому.

Один JQuery Wrapper (за пример):

$("#myDiv").html('<div id="mySecondDiv"></div>');

$("#myDiv").append('<div id="mySecondDiv"></div>');

Два jQuery Wrappers (за пример):

var mySecondDiv=$('<div id="mySecondDiv"></div>');
$('#myDiv').html(mySecondDiv);

var mySecondDiv=$('<div id="mySecondDiv"></div>');
$('#myDiv').append(mySecondDiv);

У вас есть несколько вариантов использования. Если вы хотите заменить контент, .htmlэто отличный вызов, так как его эквивалент innerHTML = "...". Однако, если вы просто хотите добавить контент, дополнительный $()набор обёрток не требуется.

Используйте только две оболочки, если вам нужно манипулировать добавленным divпозже. Даже в этом случае вам все еще может понадобиться только один:

var mySecondDiv = $("<div id='mySecondDiv'></div>").appendTo("#myDiv");
// other code here
mySecondDiv.hide();

Ты видишь? Конкатенация строк здесь уже приводит к ошибке (неэкранированная кавычка). смотри мой пост: P
kizzx2

20

если .addвы имеете в виду .append, то результат тот же, если #myDivпуст.

производительность одинакова? не знаю

.html(x) в конечном итоге делает то же самое, что и .empty().append(x)


Кроме того, первый, очевидно, будет иметь идентификатор mySecondDiv, в то время как другой не будет иметь идентификатора. И синтаксис должен быть .html ("<div id = 'mySecondDiv'> </ div>") с использованием двойных кавычек, чтобы можно было использовать одинарные кавычки.
рянулит


7

Вы можете получить второй метод для достижения того же эффекта:

var mySecondDiv = $('<div></div>');
$(mySecondDiv).find('div').attr('id', 'mySecondDiv');
$('#myDiv').append(mySecondDiv);

Лука упомянул, что html()просто вставляет HTML, что приводит к более высокой производительности.

В некоторых случаях вы бы выбрали второй вариант, рассмотрите:

// Clumsy string concat, error prone
$('#myDiv').html("<div style='width:'" + myWidth + "'px'>Lorem ipsum</div>");

// Isn't this a lot cleaner? (though longer)
var newDiv = $('<div></div>');
$(newDiv).find('div').css('width', myWidth);
$('#myDiv').append(newDiv);

5
Это крайне неэффективный (и неработающий) код jQuery. Если вы хотите избежать объединения, сделайте это: (также примечание pxне требуется):$('<div />', { width: myWidth }).appendTo("#myDiv");
Дуг Нейнер

3
Как это "не полезно"? На плакате спрашивалось «разница» (ключевое слово «против»), поэтому я говорю ему разницу. Кодекс многословен, но я бы не сказал «неэффективно» только потому, что это не один вкладыш. Разве мы не должны быть многословны, когда объясняем вещи людям?
kizzx2


2

Кроме данных ответов, в случае, если у вас есть что-то вроде этого:

<div id="test">
    <input type="file" name="file0" onchange="changed()">
</div>
<script type="text/javascript">
    var isAllowed = true;
    function changed()
    {
        if (isAllowed)
        {
            var tmpHTML = $('#test').html();
            tmpHTML += "<input type=\"file\" name=\"file1\" onchange=\"changed()\">";
            $('#test').html(tmpHTML);
            isAllowed = false;
        }
    }
</script>

Это означает, что вы хотите автоматически добавить еще одну загрузку файла, если какие-либо файлы были загружены, упомянутый код не будет работать, потому что после загрузки файла первый элемент загрузки файла будет воссоздан и, следовательно, загруженный файл будет удален из него. , Вместо этого вы должны использовать .append ():

    function changed()
    {
        if (isAllowed)
        {
            var tmpHTML = "<input type=\"file\" name=\"file1\" onchange=\"changed()\">";
            $('#test').append(tmpHTML);
            isAllowed = false;
        }
    }

0

Это случилось со мной. Версия Jquery: 3.3. Если вы просматриваете список объектов и хотите добавить каждый объект как дочерний элемент некоторого родительского элемента dom, то .html и .append будут вести себя очень по-разному. .htmlзакончится добавлением только последнего объекта к родительскому элементу, тогда как .appendвсе объекты списка будут добавлены как дочерние элементы родительского элемента.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.