Який найефективніший спосіб створити HTML-елементи за допомогою jQuery?


425

Останнім часом я роблю багато модальних спливаючих вікон, а що ні, для чого я використовував jQuery. Метод, який я використовував для створення нових елементів на сторінці, в основному був уздовж наступних напрямків:

$("<div></div>");

Однак у мене виникає відчуття, що це не найкращий чи найефективніший спосіб зробити це. Який найкращий спосіб створити елементи в jQuery з точки зору продуктивності?

Ця відповідь має орієнтири для поданих нижче пропозицій.


1
Поекспериментуйте і з видаленням стилів і подивіться, чи це прискорює роботу. Я знаходжу додаток CSS і оновлення сповільнюють все найбільше на великих сторінках для мене.
CVertex

3
Остерігайтеся передчасної оптимізації - якщо ви цього не робите одночасно для сотень елементів DOM або використовуєте ДУЖЕ старі браузери, ви, мабуть, не помітите жодної різниці в продуктивності браузера.
Blazemonger

1
@Blazemonger Мені було не стільки, що мені потрібен був більш ефективний метод створення елементів DOM, але ситуація, в якій я потрапила, змусила задуматися про те, які є альтернативи та наскільки вони можуть бути ефективними.
Darko Z

2
jQuery - це бібліотека - з цієї причини ви майже завжди будете нести накладні витрати на продуктивність: це як спілкуватися з ким-небудь через перекладача. Якщо ви не хочете використовувати необроблений JavaScript, скористайтеся тим, як швидко записати $ ('<div>') і прийміть хіт продуктивності.
Danny Bullis

1
jsben.ch/#/bgvCV <= цей орієнтир повинен відповісти на ваше запитання
EscapeNetscape

Відповіді:


307

Я використовую $(document.createElement('div')); тести показує, що ця техніка є найшвидшою. Я припускаю, що це тому, що jQuery не повинен ідентифікувати його як елемент і створювати сам елемент.

Ви дійсно повинні запускати орієнтири з різними двигунами Javascript і зважувати свою аудиторію за результатами. Прийміть рішення звідти.


16
jQuery "додає" його до DOM? Де? Це не має для мене особливого сенсу - куди б подітися діва?
страгер

28
створений div в jquery потрібно додати так само, як у javascript. $ ('<div>') сам по собі не приєднується до DOM, поки ви щось не додасте ().
Оуен

6
@David - очевидно, ти маєш рацію. Зауважу, що я додав коментар приблизно 2 роки тому саме тоді, коли я починав вивчати jQuery. Вам потрібно було б зробити appendTo, ... Оскільки коментарі, очевидно, були помилковими, я їх видалив.
tvanfosson

16
Посилання на бенчмаркінг є чудовим, але це також перевірка створення десятків тисяч елементів. Коли ви коли-небудь будете мати справу з такою кількістю елементів у типовій ситуації? Швидше за все, у вас є більші речі, про які слід побоюватися, ніж про те, як створити елемент. document.createElement "Побіг 39682 рази за 0,097 секунди", тоді як $ ('<div>') "забіг 12,642 за 0,068 секунди." Я б сказав, якщо щось може запустити тисячі разів за секунду, ви в безпеці.
Danny Bullis

20
Крім того, використовуючи $ (document.createElement ('div')); Я б сказав, що це менш ефективно, тому що потрібно писати більше часу, щоб отримати істотну кількість переваг, які ви отримаєте в браузері, якщо ви створюватимете один елемент тут і там. Технічно jQuery сам по собі менш ефективний як бібліотека через витрати на пошук та накладні витрати, які ви несете за його використання. Якщо хтось має намір заощадити дорогоцінні тисячні мільйонні секунди, використовуючи document.createElement замість $ ('<div>'), то він не повинен використовувати jQuery:], тому що $ ('<div>') - одна з причин, якими ви користуєтесь цим!
Danny Bullis

163

особисто я запропонував (для читабельності):

$('<div>');

деякі цифри з пропозицій поки що (safari 3.2.1 / mac os x):

var it = 50000;

var start = new Date().getTime();
for (i = 0; i < it; ++i)  {
  // test creation of an element 
  // see below statements
}
var end = new Date().getTime();
alert( end - start );                

var e = $( document.createElement('div') );  // ~300ms
var e = $('<div>');                          // ~3100ms
var e = $('<div></div>');                    // ~3200ms
var e = $('<div/>');                         // ~3500ms              

15
З Документів jquery: 'Під час створення окремих елементів використовуйте тег закриття або формат XHTML. Наприклад, щоб створити проміжок, використовуйте $ ("<span />") або $ ("<span> </span>"), а не без косої риски / тегу. "
tvanfosson

6
@Owen, така поведінка - це помилка, а не особливість. Сміття, сміття - просто так трапляється, що сміття, яке ви отримуєте, є прийнятним. Не покладайтеся на нього між версіями jQuery, якщо тільки специфікація для цієї функції не зміниться.
страгер

2
Як і очікувалося, побачити подібні номери в Mac OS X Chrome (100 мс для createElement () проти 500 мс розбору тексту) та Mac OS X Firefox (350 мс проти 1000 мс). Дякуємо за написання тестового циклу.
Annika Backstrom

3
@tvanfosson Це, мабуть, змінилося, в поточних документах написано: "Коли параметр має один тег (з необов'язковим тегом закриття або швидким закриттям) - $ (" <img /> ") або $ (" <img> " ), $ ("<a> </a>") або $ ("<a>") - jQuery створює елемент за допомогою нативної функції createElement () JavaScript. "
метатрон

3
@MarcStober Жодного правопорушення не вчинено. Це все ще тут: http://api.jquery.com/jQuery/#jQuery2 . Документи згадують необов'язковий закриваючий тег або швидке закриття
метатрон

155

Питання:

Який найефективніший спосіб створити HTML-елементи за допомогою jQuery?

Відповідь:

Оскільки мова йде про jQueryтоді, я думаю, що краще використовувати цей (чистий) підхід (ви використовуєте)

$('<div/>', {
    'id':'myDiv',
    'class':'myClass',
    'text':'Text Only',
}).on('click', function(){
    alert(this.id); // myDiv
}).appendTo('body');

DEMO.

Таким чином, ви навіть можете використовувати обробники подій для конкретного елемента, наприклад

$('<div/>', {
    'id':'myDiv',
    'class':'myClass',
    'style':'cursor:pointer;font-weight:bold;',
    'html':'<span>For HTML</span>',
    'click':function(){ alert(this.id) },
    'mouseenter':function(){ $(this).css('color', 'red'); },
    'mouseleave':function(){ $(this).css('color', 'black'); }
}).appendTo('body');

DEMO.

Але коли ви маєте справу з безліччю динамічних елементів, вам слід уникати додавання подій handlersконкретного елемента, натомість слід використовувати делегований обробник подій, наприклад

$(document).on('click', '.myClass', function(){
    alert(this.innerHTML);
});

var i=1;
for(;i<=200;i++){
    $('<div/>', {
        'class':'myClass',
        'html':'<span>Element'+i+'</span>'
    }).appendTo('body');
}

DEMO.

Отже, якщо ви створюєте та додаєте сотні елементів з тим самим класом, тобто ( myClass), то для обробки подій буде витрачено менше пам'яті, тому що лише один обробник буде там, щоб виконувати завдання для всіх динамічно вставлених елементів.

Оновлення: оскільки ми можемо використовувати наступний підхід для створення динамічного елемента

$('<input/>', {
    'type': 'Text',
    'value':'Some Text',
    'size': '30'
}).appendTo("body");

Але sizeатрибут не може бути встановлений з допомогою цього підходу з використанням jQuery-1.8.0або пізніше , і тут старий звіту про помилку , подивіться на цьому прикладі , використовуючи jQuery-1.7.2який показує , що sizeатрибут встановлений з 30допомогою описаного вище прикладу , але використовуючи той же підхід , який ми не можемо набір sizeатрибутів , використовуючи jQuery-1.8.3, тут - це непрацююча скрипка . Отже, для встановлення sizeатрибуту ми можемо використовувати наступний підхід

$('<input/>', {
    'type': 'Text',
    'value':'Some Text',
    attr: { size: "30" }
}).appendTo("body");

Або цей

$('<input/>', {
    'type': 'Text',
    'value':'Some Text',
    prop: { size: "30" }
}).appendTo("body");

Ми можемо передати в attr/propякості дочірнього об'єкта , але він працює в jQuery-1.8.0 and laterверсіях перевірити цей приклад , але він не працюватиме в jQuery-1.7.2 or earlier(не тестується у всіх попередніх версіях).

BTW, взяті з jQueryповідомлення про помилку

Є кілька рішень. Перший - це взагалі не використовувати його, оскільки це не економить вам простору, і це покращує чіткість коду:

Вони радили використовувати наступний підхід ( працює і в попередніх , апробований 1.6.4)

$('<input/>')
.attr( { type:'text', size:50, autofocus:1 } )
.val("Some text").appendTo("body");

Отже, краще використовувати такий підхід, ІМО. Це оновлення робиться після того, як я прочитав / знайшов цю відповідь, і в цій відповіді видно, що якщо ви використовуєте 'Size'(capital S)замість 'size'цього, воно буде просто добре працювати , навіть уversion-2.0.2

$('<input>', {
    'type' : 'text',
    'Size' : '50', // size won't work
    'autofocus' : 'true'
}).appendTo('body');

Читайте також про технічну підтримку , оскільки є різниця Attributes vs. Properties, вона залежить від версій.


Що це за sintax це $ ('<div />', {.........}), я шукав його, і знайшов щось подібне, використовуючи $ ('<div>) .attr ( {......})?
Рафаель Руїз Табарес

@RafaelRuizTabares, $('<div>', {...})ви передаєте об'єкт, який містить усі атрибути, і $('<div>').attr({...})ви створюєте елемент без будь-яких атрибутів, але встановлюєте атрибути, використовуючи attr()метод пізніше.
Альфа

@TheAlpha, де я можу знайти інформацію про те, що можна написати всередині {}? Тому що я бачу, що вони є атрибутами та подіями, але для <div> ви також використовуєте html. Дякую!
Рафаель Руїз Табарес

Пошук jQuery.comвеб-сайту може бути корисним @RafaelRuizTabares, або google it :-)
The Alpha

2
Це, безумовно, найбільш чистий спосіб читати! Можливо, це не швидкий шлях, але, звичайно, менше помилок, схильних до додавання рядків. Дякуємо @TheAlpha
Арес

37

Насправді, якщо ви робите $('<div>'), jQuery також використовуватиме document.createElement().

(Просто подивіться на рядок 117 ).

Існує деякий накладний набір функціональних викликів, але якщо продуктивність не є критичною (ви створюєте сотні [тисяч] елементів), немає великої причини повернутися до звичайного DOM .

Просто створення елементів для нової веб-сторінки, мабуть, випадок, коли ви найкраще будете дотримуватися способу jQuery .


20

Якщо у вас багато вмісту HTML (більше, ніж лише один div), ви можете розглянути можливість побудови HTML на сторінці в прихованому контейнері, а потім оновити його та зробити його видимим при необхідності. Таким чином, велика частина вашої розмітки може бути попередньо проаналізована браузером і уникнути пошкодження JavaScript при виклику. Сподіваюся, це допомагає!


Дякую за пораду. Я раніше використовував такий підхід, проте в цьому конкретному випадку я хочу особливо знати про створення елементів.
Darko Z

20

Це не правильна відповідь на питання, але все ж я хотів би поділитися цим ...

Використання просто document.createElement('div')та пропуск JQuery значно покращить продуктивність, коли ви хочете зробити безліч елементів під час руху та додавати до DOM.


16

Я думаю, ви використовуєте найкращий метод, хоча ви можете оптимізувати його до:

 $("<div/>");

11

Вам не потрібно сильної продуктивності операції, яку ви будете виконувати вкрай рідко з точки зору процесора.


Залежить від того, як часто ви це робите.
Річ Бредшоу

8
ОП створює модальне спливаюче вікно . Ця операція не повторюється тисячі разів за секунду. Натомість це повторюється, можливо, раз на кілька секунд, максимум. Використання jQuery(html :: String)методу цілком чудово. Якщо ситуація не буде надзвичайно незвичною, навряд чи вдасться досягти кращого сприйнятого результату. Витрачайте енергію оптимізації на випадки, які могли б її використовувати. Крім того, jQuery оптимізовано для швидкості багатьма способами. Робіть з ним розумні речі і довіряйте, але перевіряйте, що це швидко.
yfeldblum

9

Вам доведеться зрозуміти, що значення продуктивності створення елементів не має значення в контексті використання в першу чергу jQuery.

Майте на увазі, що немає реальної мети створення елемента, якщо ви його фактично не збираєтеся використовувати.

Можливо, ви будете спокушені перевірити продуктивність на кшталт $(document.createElement('div'))порівняно, $('<div>')і отримати великі підвищення продуктивності від використання, $(document.createElement('div'))але це лише елемент, якого ще немає у DOM.

Однак, зрештою, ви хочете використовувати елемент так чи інакше, тому справжній тест повинен включати f.ex. .appendTo ();

Подивимось, якщо ви перевіряєте наступне один на одного:

var e = $(document.createElement('div')).appendTo('#target');
var e = $('<div>').appendTo('#target');
var e = $('<div></div>').appendTo('#target');
var e = $('<div/>').appendTo('#target');

Ви помітите, що результати будуть різними. Іноді один спосіб є більш ефективним, ніж інший. І це лише тому, що кількість фонових завдань на вашому комп’ютері змінюється з часом.

Перевірте себе тут

Отже, зрештою, ви хочете вибрати найменший і найчитабельніший спосіб створення елемента. Таким чином, принаймні, ваші файли скриптів будуть найменшими. Можливо, більш вагомий фактор точки продуктивності, ніж спосіб створення елемента, перш ніж використовувати його в DOM.


Я знаю, що це по-старому, але немає необхідності в jQuery у першому прикладі:document.getElementById('target).appendChild(document.createElement('div'));
hisdrewness


7

Один момент полягає в тому, що зробити це може бути простіше:

$("<div class=foo id=bar style='color:white;bgcolor:blue;font-size:12pt'></div>")

Потім зробити все це з дзвінками jquery.


3

Я використовую jquery.min v2.0.3. Для мене краще використовувати наступне:

var select = jQuery("#selecter");
jQuery("`<option/>`",{value: someValue, text: someText}).appendTo(select);

наступним чином:

var select = jQuery("#selecter");
jQuery(document.createElement('option')).prop({value: someValue, text: someText}).appendTo(select);

Час обробки першого коду набагато менший, ніж другого коду.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.