jQuery.click () vs onClick


558

У мене є величезний додаток jQuery, і я використовую наведені нижче два способи для подій клацання.

Перший метод

HTML

<div id="myDiv">Some Content</div>

jQuery

$('#myDiv').click(function(){
    //Some code
});

Другий метод

HTML

<div id="myDiv" onClick="divFunction()">Some Content</div>

Виклик функції JavaScript

function divFunction(){
    //Some code
}

У своїй заявці я використовую або перший, або другий метод. Який з них кращий? Краще для продуктивності? А стандарт?


9
Дізнатися про різні способи приєднання обробників подій та їх переваги / недоліки можна тут: quirksmode.org/js/introevents.html . jQuery - це просто приємна обгортка для розширеної реєстрації подій.
Фелікс Клінг

12
Не забудьте помістити функцію клацання всередину $ (document) .ready (function ().
joan16v

Відповіді:


559

Використовуючи $('#myDiv').click(function(){це краще як слід стандартної реєстрації подій моделі. (jQuery внутрішньо використовує addEventListenerта attachEvent).

В основному, реєстрація події сучасним способом - це ненав’язливий спосіб поводження з подіями. Крім того, щоб зареєструвати більше одного слухача події для цілі, ви можете викликати addEventListener()ту саму ціль.

var myEl = document.getElementById('myelement');

myEl.addEventListener('click', function() {
    alert('Hello world');
}, false);

myEl.addEventListener('click', function() {
    alert('Hello world again!!!');
}, false);

http://jsfiddle.net/aj55x/1/

Навіщо використовувати addEventListener? (Від MDN)

addEventListener - це спосіб зареєструвати слухача подій, як зазначено в W3C DOM. Його переваги полягають у наступному:

  • Це дозволяє додати більше ніж один обробник для події. Це особливо корисно для бібліотек DHTML або розширень Mozilla, які повинні добре працювати, навіть якщо використовуються інші бібліотеки / розширення.
  • Це дає точний дрібний контроль над фазою, коли слухач активується (захоплюючий та бульбашковий)
  • Він працює на будь-якому елементі DOM, а не тільки на елементах HTML.

Детальніше про сучасну реєстрацію подій -> http://www.quirksmode.org/js/events_advanced.html

Інші методи, такі як встановлення атрибутів HTML , наприклад:

<button onclick="alert('Hello world!')">

Або властивості елементів DOM , наприклад:

myEl.onclick = function(event){alert('Hello world');}; 

вони старі, і їх можна легко записати.

Слід уникати атрибутів HTML, оскільки він робить розмітку більшою та менш читаною. Занепокоєння змістом / структурою та поведінкою недостатньо відокремлено, що робить помилку важче.

Проблема методу властивостей елемента DOM полягає в тому, що лише один обробник подій може бути прив'язаний до елемента на подію.

Докладніше про традиційну обробку подій -> http://www.quirksmode.org/js/events_tradmod.html

Довідка про MDN: https://developer.mozilla.org/en-US/docs/DOM/event


13
Скажімо, ви $('#myDiv').click(function(){спершу запускаєте код, після чого з JavaScript ви генеруєте динамічно 20 рядків HTML, і кожен рядок має на ньому кнопку, яка при натисканні на JavaScript вимагає виконання тієї самої функції. Якщо ви зробите це спочатку, то він не працюватиме, оскільки обробник подій був доданий до створення HTML. Здавалося б, простіше просто вписати в onclick="functionName()"динамічно генерований HTML, тоді кнопка працює відразу. Або ви знаєте більш елегантне рішення для цієї ситуації?
zuallauz

17
@zuallauz для цього випадку jQuery пропонує .delegate()функцію. Він додасть подію до будь-якого елемента, який з’явиться в майбутньому на сайті.
Зефірин

17
@SimonRobb .liveзастаріло. Використовуйте .delegateдля більш старих версій або використовуйте .onдля новіших версій jQuery.
Selvakumar Arumugam

4
@ Вега, Добрі моменти. Що з читабельністю? Тепер вам потрібно шукати всі посилані файли JS на сторінці, щоб побачити всі обробники клацань елемента за ідентифікатором елемента, а не шукати ім'я функції. Що ти береш за це?
супертонський

6
Я згоден з @supertonsky. Я НЕ СУМНО погоджуюся з тим, що $ ('# myDiv'). Click (function () {краще. У великому додатку javascript прив'язка до події стає важко знайти всі посилання, що прив'язують до цієї цілі. Чи прив'язка до класу , ідентифікатор, дитина посилається на тег html? І що трапиться, якщо css змінить і назви класів, які ви обов'язково повинні змінити? З мого досвіду роботи з іншими кодами це стає дуже некрасивим дуже швидко
Jon,

65

Для кращої роботи використовуйте рідний JavaScript. Для швидшого розвитку використовуйте jQuery. Перевірте порівняння продуктивності на jQuery та Native Element Performance .

Я зробив тест на 32-розрядний Firefox 16.0 на Windows Server 2008 R2 / 7 64-бітний

$('span'); // 6,604 operations per second
document.getElementsByTagName('span'); // 10,331,708 operations/sec

Для подій клацання перевірте події Native Browser vs тригер jquery або jQuery vs Прив’язка подій Native Click .

Тестування в Chrome 22.0.1229.79 32-розрядної версії на 64-розрядному Windows Server 2008 R2 / 7

$('#jquery a').click(window.testClickListener); // 2,957 operations/second

[].forEach.call( document.querySelectorAll('#native a'), function(el) {
    el.addEventListener('click', window.testClickListener, false);
}); // 18,196 operations/second

9
jQuery повинен мати можливість працювати в багатьох різних середовищах, що робить його більш зручним і легше писати, підтримувати, але якщо швидкість є найважливішою, то jQuery - це не відповідь
Coops

Будьте уважні при використанні forEach, тому що не всі браузери сумісні, я думаю, що не для IE, наприклад. Можливо, поліфіл буде корисний.
khaled_webdev

39

Як я розумію, ваше питання насправді не в тому, використовувати jQuery чи ні. Це швидше: чи краще пов'язувати події вбудованими в HTML або через слухачів подій?

Вбудоване зв’язування застаріле. Більше того, таким чином ви можете прив’язати лише одну функцію до певної події.

Тому рекомендую використовувати слухачів подій. Таким чином, ви зможете прив’язати багато функцій до однієї події та при необхідності від’єднати їх пізніше. Розглянемо цей чистий код JavaScript:

querySelector('#myDiv').addEventListener('click', function () {
    // Some code...
});

Це працює в більшості сучасних браузерів.

Однак якщо ви вже включаєте jQuery у свій проект - просто використовуйте jQuery: .onабо .clickфункцію.


Можна зареєструвати кілька функцій за допомогою вбудованого HTML, як <div onclick = "handler1 (); handler2 (); handler3 ();"> </div>
Кіра,

2
Таким чином ви все ще реєструєте лише один "вираз". Наприклад, якщо handler1виникла помилка, handler2і handler3ніколи не дзвонить. Крім того, ви не можете динамічно додавати та видаляти певні функції з слухача. І останнє , але не в останню чергу, handler1, handler2і handler3повинні бути оголошені в глобальному масштабі , який є запах.
Michał Miszczyszyn

Використання try..catchвсередині функцій не буде працювати, якщо не handler2визначено. FYI вбудований JavaScript очевидно не працює, коли JS відключений у браузері користувача, будь ласка, не дезінформуйте інших.
Michał Miszczyszyn

Я згадував, що не впевнений у відключенні JavaScript. Я не дезінформую або обманюю інших
Кіра

У цьому випадку ви можете спробувати наступний <div onclick = "function () {try {handler1 (); handler2 (); handler3 ();} catch {}}"> </div>
Кіра

15

Ви можете їх комбінувати, використовувати jQuery, щоб прив'язати функцію до клацання

<div id="myDiv">Some Content</div>

$('#myDiv').click(divFunction);

function divFunction(){
 //some code
}

14

$('#myDiv').clickкраще, тому що він відокремлює код JavaScript від HTML . Треба намагатися не змінювати поведінку та структуру сторінки . Це дуже допомагає.


2
Ця відповідь має сенс, оскільки люди, які розробляють та пишуть js речі, у більшості випадків різні. І мені здається дивним підкріпити це майже через 4 роки з моменту публікації !!
LearningEveryday

14

Займіться цим, оскільки це дасть вам як стандарт, так і продуктивність.

 $('#myDiv').click(function(){
      //Some code
 });

Оскільки другий метод - простий код JavaScript і швидший, ніж jQuery. Але тут продуктивність буде приблизно однаковою.


11

IMHO, onclick є кращим методом над .click лише тоді, коли виконуються наступні умови:

  • на сторінці багато елементів
  • лише одна подія, яка повинна бути зареєстрована для події клацання
  • Ви турбуєтеся про продуктивність мобільних пристроїв / заряд акумулятора

Я сформував цю думку через те, що двигуни JavaScript на мобільних пристроях у 4–7 разів повільніше, ніж їх аналоги на робочому столі, які були зроблені в тому ж поколінні. Я ненавиджу це, коли відвідую сайт на своєму мобільному пристрої і отримую невдалий прокручування, оскільки jQuery пов'язує всі події за рахунок мого досвіду роботи та часу автономної роботи. Ще один останній підтримуючий фактор, хоча це має викликати занепокоєння урядових установ;), у нас з’явилося спливаюче вікно IE7 із полем повідомлень про те, що процес JavaScript триває довго ... чекати або скасувати процес. Це траплялося кожного разу, коли було багато елементів, з якими можна зв’язатись через jQuery.


10

Різниця у творах. Якщо ви використовуєте click (), ви можете додати кілька функцій, але якщо ви використовуєте атрибут, буде виконуватися лише одна функція - остання.

DEMO

HTML

<span id="JQueryClick">Click #JQuery</span> </br>
<span id="JQueryAttrClick">Click #Attr</span> </br>

JavaScript

$('#JQueryClick').click(function(){alert('1')})
$('#JQueryClick').click(function(){alert('2')})

$('#JQueryAttrClick').attr('onClick'," alert('1')" ) //This doesn't work
$('#JQueryAttrClick').attr('onClick'," alert('2')" )

Якщо ми говоримо про продуктивність, в будь-якому випадку безпосередньо використання завжди швидше, але за допомогою атрибута ви зможете призначити лише одну функцію.


Ми можемо виконати більше ніж одну функцію, використовуючи такий атрибут, як $ ('# JQueryAttrClick'). Attr ('onClick', "alert ('2'); alert ('3'); alert ('4')")
Кіра

8

Тут є ключовим питанням відокремлення проблем, тому прив'язка подій є загальноприйнятим методом. Це в основному те, про що сказано багато існуючих відповідей.

Однак не кидайте ідею декларативної розмітки занадто швидко. У ній є своє місце, і такі рамки, як Angularjs, є центральним.

Повинно бути розуміння того, що ціле <div id="myDiv" onClick="divFunction()">Some Content</div>було збентежене настільки сильно, оскільки ним зловживали деякі розробники. Так воно дійшло до точки блюзнірських розмірів, як і раніше tables. Деякі розробники насправді уникають tablesтабличних даних. Це ідеальний приклад людей, які діють без розуміння.

Хоча мені подобається ідея зберігати свою поведінку окремо від моїх поглядів. Я не бачу жодної проблеми з розміткою, яка б декларувала, що вона робить (не як це робить, це поведінка). Він може бути у формі фактичного атрибута onClick або спеціального атрибуту, як і компоненти завантажувального Javascript.

Таким чином, поглянувши просто на розмітку, ви зможете побачити, що робиться, замість того, щоб намагатись зворотного пошуку прив'язних файлів JavaScript.

Отже, в якості третьої альтернативи вищезазначеному, використовуючи атрибути даних, щоб декларативно оголосити поведінку в межах розмітки. Поведінка залишається поза зором, але з першого погляду ви можете побачити, що відбувається.

Приклад завантаження:

<button type="button" class="btn btn-lg btn-danger" data-toggle="popover" title="Popover title" data-content="And here's some amazing content. It's very engaging. Right?">Click to toggle popover</button>

Джерело: http://getbootstrap.com/javascript/#popovers

Примітка Основним недоліком другого прикладу є забруднення глобального простору імен. Цього можна обійти, використовуючи третю вище альтернативу, або рамки, такі як Angular, та їх атрибути ng-click з автоматично областю застосування.


4

Жоден з них не є кращим, оскільки їх можна використовувати для різних цілей. onClick(насправді має бутиonclick ) працює трохи краще, але я дуже сумніваюся, що ви помітите різницю там.

Варто зазначити, що вони роблять різні речі: .clickїх можна прив’язати до будь-якої колекції jQuery, тоді як onclickїї потрібно використовувати вбудовано на елементах, до яких ви хочете, щоб вони були пов'язані. Ви також можете прив’язати до використання лише одну подію onclick, тоді як .clickдозволяє продовжувати зв'язувати події.

На мою думку, я б відповідав цьому і просто користувався .clickскрізь, а весь свій JavaScript код зберігати разом і відокремлювати від HTML.

Не використовуйте onclick. Немає жодних причин використовувати його, якщо ви не знаєте, що робите, і, мабуть, не знаєте.


2
Навіть якщо "краще" чітко не визначено, майже ніколи не є ідеєю безпосередньо вводити обробників подій у вашу розмітку
Jay,

@Jayraj, коли я коли-небудь сказав у своїй відповіді, що це була гарна ідея?
Вибухові таблетки

3
Сказавши .clickне краще, ніж onclick("Ні один краще "), малося на увазі, що onclickце майже, або такий же хороший спосіб написання коду, коли насправді .clickце краща практика за милю. Вибачте, але IMHO вам слід перефразувати свою відповідь
Jay

2
@ExplosionPills Я б видалив частину відповіді, в якій сказано, що ні краще. Абзац в кінці звучить як суперечність.
Хуан Мендес

4
<whatever onclick="doStuff();" onmouseover="in()" onmouseout="out()" />

події onclick, onmouseover, onmouseout і т. д. насправді погані за ефективністю (в основному, в Internet Explorer , в першу чергу) Якщо ви кодуєте Visual Studio , коли ви запускаєте сторінку з ними, кожен з них створить окремий блок SCRIPT, що займає пам'ять, і, таким чином, уповільнює продуктивність.

Не кажучи вже про те, що у вас виникне розбіжність : JavaScript і макети повинні бути розділені!

Завжди краще створити evenHandlers для будь-якої з цих подій, одна подія може захоплювати сотні / тисячі предметів, а не створювати тисячі окремих блоків сценаріїв для кожного!

(Також все, що всі говорять.)


3

Ну, одна з головних ідей jQuery - це відокремити JavaScript від бридкого HTML- коду. Перший метод - це шлях.


3

Здебільшого, рідні методи JavaScript є кращим вибором у порівнянні з jQuery, коли ефективність є єдиним критерієм, але jQuery використовує JavaScript і полегшує розробку. Ви можете використовувати jQuery, оскільки він не надто погіршує продуктивність. У вашому конкретному випадку різниця в продуктивності є незначною.


2

Перший метод використання onclick- це не jQuery, а просто Javascript, тому ви не отримаєте накладні витрати jQuery. Шлях jQuery може розширюватися за допомогою селекторів, якщо вам потрібно було додати його до інших елементів, не додаючи обробник подій до кожного елемента, але, як у вас зараз, це лише питання, чи потрібно вам використовувати jQuery чи ні.

Особисто, оскільки ви використовуєте jQuery, я би дотримувався цього, оскільки він є послідовним і не відокремлює розмітку від сценарію.


1
Приклад jQuery - це практично те саме, що document.querySelector('#something').addEventListener(...або подібний у звичайному Javascript, так що справа не в цьому. Аналогічно, ви можете вловлювати події бульбашок з дочірніх вузлів у Javascript, а не лише за допомогою ярликів jQuery. Суть справи в тому, щоб ці події мали бути в контролері (файл визначення поведінки JavaScript), а не у вікні (розкиданий тут і там у html, вимагаючи глобальних змінних функцій чи ще гірше, вбудований код.)
NoBugs

2

Перший спосіб - віддати перевагу. Він використовує вдосконалену модель реєстрації подій [s] , що означає, що ви можете приєднати декілька обробників до одного елемента. Ви можете легко отримати доступ до об'єкта події, а обробник може жити в будь-якій області функцій. Крім того, він динамічний, тобто його можна викликати в будь-який час і особливо добре підходить для елементів, що динамічно створюються. Чи ви безпосередньо використовуєте jQuery, іншу бібліотеку або рідні методи, насправді не має значення.

Другий метод, використовуючи вбудовані атрибути, потребує безлічі глобальних функцій (що призводить до забруднення простору імен) і змішує зміст / структуру (HTML) з поведінкою (JavaScript). Не використовуйте це.

На ваше питання щодо продуктивності чи стандартів не можна легко відповісти. Два способи просто абсолютно різні і роблять різні речі. Перший - сильніший, а другий - зневажається (вважається поганим стилем).


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