jQuery document.createElement эквивалент?

1251

Я рефакторинг старого кода JavaScript, и происходит много манипуляций с DOM.

var d = document;
var odv = d.createElement("div");
odv.style.display = "none";
this.OuterDiv = odv;

var t = d.createElement("table");
t.cellSpacing = 0;
t.className = "text";
odv.appendChild(t);

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

var odv = $.create("div");
$.append(odv);
// And many more

Но я не уверен, что это лучше.

Роб Стивенсон-Леггетт
источник
jsben.ch/#/ARUtz - тест для jquery и createElement
EscapeNetscape,
Возможный дубликат создания элемента div в jQuery
T.Todua
Uncaught TypeError: $ .create не является функцией
Tyguy7

Ответы:

1290

Вот ваш пример в строке «один».

this.$OuterDiv = $('<div></div>')
    .hide()
    .append($('<table></table>')
        .attr({ cellSpacing : 0 })
        .addClass("text")
    )
;

Обновление : я думал, что обновлю этот пост, так как он все еще получает довольно мало трафика. В комментариях ниже есть некоторое обсуждение $("<div>")vs против $("<div></div>")vs $(document.createElement('div'))как способа создания новых элементов, и который является «лучшим».

Я собрал небольшой тест , и вот примерные результаты повторения вышеупомянутых опций 100 000 раз:

jQuery 1.4, 1.5, 1.6

               Chrome 11  Firefox 4   IE9
<div>            440ms      640ms    460ms
<div></div>      420ms      650ms    480ms
createElement    100ms      180ms    300ms

JQuery 1,3

                Chrome 11
<div>             770ms
<div></div>      3800ms
createElement     100ms

JQuery 1.2

                Chrome 11
<div>            3500ms
<div></div>      3500ms
createElement     100ms

Я думаю, это не является большим сюрпризом, но document.createElementэто самый быстрый метод. Конечно, прежде чем вы приступите к рефакторингу всей вашей кодовой базы, помните, что различия, о которых мы здесь говорим (во всех, кроме архаичных версиях jQuery), равняются дополнительным 3 миллисекундам на тысячу элементов .


Обновление 2

Обновлен для jQuery 1.7.2 и поставил эталонный тест, JSBen.chкоторый, вероятно, немного более научен, чем мои примитивные тесты, плюс он может быть теперь краудсорсинг!

http://jsben.ch/#/ARUtz

nickf
источник
70
Вы обнаружите, что document.createElement намного быстрее, чем jQuery, преобразующий вашу HTML-строку в элемент. (на всякий случай, если у вас есть желание сделать вещи более эффективными)
Sugendran
25
Это верно для jQuery <1,3 Это эквивалент скорости теперь я верю.
Роб Стивенсон-Леггетт
15
@Kevin, это правда, однако это заставляет jQuery выполнять больше работы (он запускает его через регулярное выражение для добавления закрывающего тега), поэтому я предпочитаю метод выше. Кроме того, он отличает ваш код от $('div')визуально очень похожего, но функционально отличающегося друг от друга.
Nickf
14
Таким образом, комбинация @Sungendran & @nickf будет $(document.createElement('div'))и должна быть самой быстрой?
Kolky
14
Я думаю, что «правильный» путь - это $ ('<div />'), поскольку, IMO, имеет еще больше «смысла», поскольку совершенно очевидно, что вы создаете узел. Плохо, что этот способ нарушает подсветку синтаксиса во всех редакторах = (
Эрик Эскобедо,
139

Простое указание HTML-элементов, которые вы хотите добавить в конструктор jQuery $(), вернет объект jQuery из недавно созданного HTML, который можно добавить в DOM с помощью append()метода jQuery .

Например:

var t = $("<table cellspacing='0' class='text'></table>");
$.append(t);

Затем вы можете заполнить эту таблицу программно, если хотите.

Это дает вам возможность указать любой произвольный HTML, который вам нравится, включая имена классов или другие атрибуты, которые вы можете найти более краткими, чем использование, createElementа затем настройку таких атрибутов, как cellSpacingи classNameчерез JS.

Адам Беллер
источник
7
Может быть, это было очевидно и показано вашим примером, но создание элемента DOM jQuery с использованием синтаксиса $ ("<html string>") невозможно добавить в DOM с помощью собственного метода <element> .appendChild или аналогичного. Вы должны использовать метод добавления jQuery.
Адам
4
$(htmlStr)реализован как document.createElement("div").innerHTML = htmlStr. Другими словами, он вызывает HTML-анализатор браузера. Неверно сформированный HTML по-разному ломается в IE по сравнению с другими браузерами.
Мэтью
2
У объекта @Adam jQuery есть getфункция, которая возвращает собственный элемент DOM. (Я знаю, что эта тема старая, но я добавляю ее для справки. ;-))
Константино Царухас
1
Если у вас возникли проблемы со строкой html, попробуйте проанализировать ее с помощью jQuery.parseHTML
fguillen
1
@ Adam Или, если вам проще в потоке кода / глазах, вы можете это сделать[dom element].appendChild($('<html>')[0]);
ACK_stoverflow
49

Я делаю так:

$('<div/>',{
    text: 'Div text',
    class: 'className'
}).appendTo('#parentDiv');
ками
источник
44

поскольку jQuery1.8использование $.parseHTML()для создания элементов - лучший выбор.

Есть два преимущества:

1.Если вы используете старый способ, который может быть чем-то вроде $(string), jQuery проверит строку, чтобы убедиться, что вы хотите выбрать HTML-тег или создать новый элемент. Используя $.parseHTML(), вы сообщаете jQuery, что хотите явно создать новый элемент, поэтому производительность может быть немного лучше.

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

    var userInput = window.prompt("please enter selector");
    $(userInput).hide();

плохой парень может <script src="xss-attach.js"></script>подшучивать над тобой. к счастью, $.parseHTML()избежать этого смущения для вас:

var a = $('<div>')
// a is [<div>​</div>​]
var b = $.parseHTML('<div>')
// b is [<div>​</div>​]
$('<script src="xss-attach.js"></script>')
// jQuery returns [<script src=​"xss-attach.js">​</script>​]
$.parseHTML('<script src="xss-attach.js"></script>')
// jQuery returns []

Тем не менее, обратите внимание, что aэто объект jQuery, а bэлемент html:

a.html('123')
// [<div>​123​</div>​]
b.html('123')
// TypeError: Object [object HTMLDivElement] has no method 'html'
$(b).html('123')
// [<div>​123​</div>​]
Брайан
источник
«Лучший выбор» для «создания [любого] элемента» может быть сильным. Ответ @ siergiej делает хорошую работу, говоря, что parseHTMLон хорош для html, поступающего из внешних источников, но что « весь импульс исчез после упаковки результатов в новый объект jQuery ». То есть, если вы хотите жестко запрограммировать создание нового HTML-элемента в jQuery- $("<div>stuff</div>")стиле , стиль, похоже, победит.
ruffin
38

ОБНОВИТЬ

Начиная с последних версий jQuery, следующий метод не назначает свойства, переданные во втором объекте

Предыдущий ответ

Я чувствую, что использование document.createElement('div')вместе с jQueryбыстрее:

$(document.createElement('div'), {
    text: 'Div text',
    'class': 'className'
}).appendTo('#parentDiv');
Ом Шанкар
источник
29

Хотя это очень старый вопрос, я подумал, что было бы неплохо обновить его свежей информацией;

Начиная с jQuery 1.8 существует функция jQuery.parseHTML (), которая теперь является предпочтительным способом создания элементов. Кроме того, есть некоторые проблемы с анализом HTML через $('(html code goes here)'), например, официальный сайт jQuery упоминает следующее в одном из примечаний к выпуску :

Расслабленный анализ HTML: вы можете снова иметь начальные пробелы или символы новой строки перед тегами в $ (htmlString). Мы по-прежнему настоятельно рекомендуем использовать $ .parseHTML () при синтаксическом анализе HTML, полученного из внешних источников, и, возможно, в будущем внесете дополнительные изменения в синтаксический анализ HTML.

Для связи с конкретным вопросом приведенный пример можно перевести на:

this.$OuterDiv = $($.parseHTML('<div></div>'))
    .hide()
    .append($($.parseHTML('<table></table>'))
        .attr({ cellSpacing : 0 })
        .addClass("text")
    )
;

что, к сожалению, менее удобно, чем использование just $(), но дает вам больший контроль, например, вы можете исключить теги сценария (он оставит встроенные сценарии, как, onclickвпрочем,):

> $.parseHTML('<div onclick="a"></div><script></script>')
[<div onclick=​"a">​</div>​]

> $.parseHTML('<div onclick="a"></div><script></script>', document, true)
[<div onclick=​"a">​</div>​, <script>​</script>​]

Кроме того, вот эталонный ответ из топ-ответа, адаптированный к новой реальности:

JSbin Link

JQuery 1.9.1

  $ .parseHTML: 88мс
  $ ($. parseHTML): 240 мс
  <div> </ div>: 138 мс
  <div>: 143 мс
  createElement: 64мс

Похоже , что parseHTMLгораздо ближе к createElementчем $(), но все импульс исчезает после того, как упаковка результатов в новый объект JQuery

siergiej
источник
11
var mydiv = $('<div />') // also works
Шимон Дудкин
источник
6
var div = $('<div/>');
div.append('Hello World!');

Самый короткий / самый простой способ создать элемент DIV в jQuery.

AcidicChip
источник
5

Я только что сделал для этого небольшой плагин jQuery: https://github.com/ern0/jquery.create

Это следует вашему синтаксису:

var myDiv = $.create("div");

Идентификатор узла DOM может быть указан как второй параметр:

var secondItem = $.create("div","item2");

Это серьезно? Нет. Но этот синтаксис лучше чем $ ("<div> </ div>") , и это очень хорошее соотношение цены и качества.

Я новый пользователь jQuery, перехожу с DOMAssistant на аналогичную функцию: http://www.domassistant.com/documentation/DOMAssistantContent-module.php

Мой плагин проще, я думаю, что attrs и контент лучше добавлять с помощью цепочек методов:

$("#container").append( $.create("div").addClass("box").html("Hello, world!") );

Также это хороший пример для простого jQuery-плагина (сотого).

ern0
источник
4

Это все довольно просто! Вот пара быстрых примеров ...


var $example = $( XMLDocRoot );

var $element = $( $example[0].createElement('tag') );
// Note the [0], which is the root

$element.attr({
id: '1',
hello: 'world'
});

var $example.find('parent > child').append( $element );
похотливый
источник
1

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

const mountpoint = 'https://jsonplaceholder.typicode.com/users'

const $button = $('button')
const $tbody = $('tbody')

const loadAndRender = () => {
  $.getJSON(mountpoint).then(data => {

    $.each(data, (index, { id, username, name, email }) => {
      let row = $('<tr>')
        .append($('<td>', { text: id }))
        .append($('<td>', {
          text: username,
          class: 'click-me',
          on: {
            click: _ => {
              console.log(name)
            }
          }
        }))
        .append($('<td>', { text: email }))

      $tbody.append(row)
    })

  })
}

$button.on('click', loadAndRender)
.click-me {
  background-color: lightgrey
}
<table style="width: 100%">
  <thead>
    <tr>
      <th>ID</th>
      <th>Username</th>
      <th>Email</th>
    </tr>
  </thead>
  <tbody>
  
  </tbody>
</table>

<button>Load and render</button>

<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>

Владислав Ладицкий
источник
-2

jQuery из коробки не имеет эквивалента createElement. Фактически большая часть работы jQuery выполняется внутренне с использованием innerHTML, а не чисто DOM-манипуляций. Как уже упоминал Адам, это то, как вы можете достичь подобных результатов.

Также доступны плагины, которые используют DOM вместо innerHTML, такие как appendDOM , DOMEC и FlyDOM, и это лишь некоторые из них. С точки зрения производительности нативный jquery по-прежнему наиболее производительный (в основном потому, что он использует innerHTML)

Джеймс Хьюз
источник
5
Вы должны получить в курсе. jQuery не использует innerHtml, но анализирует строку HTML и внутренне создает дерево DOM, используя document.createElement (). Это ядро ​​JQuery.
Винсент Роберт