jQuery.click() против onClick
У меня огромное приложение 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
}
Я использую первый или второй метод в моем приложении. Какой из них лучше? Лучше для производительности? А стандарт?
19 ответов
С помощью $('#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);
Зачем использовать 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
Для повышения производительности используйте собственный JavaScript. Для более быстрой разработки используйте jQuery. Проверьте сравнение производительности на jQuery против производительности нативных элементов.
Я провел тест в Firefox 16.0 32-разрядный на Windows Server 2008 R2 / 7 64-разрядный
$('span'); // 6,604 operations per second
document.getElementsByTagName('span'); // 10,331,708 operations/sec
Для событий щелчка, проверьте события Native Browser против триггера jquery или jQuery против привязки события Native Click.
Тестирование в Chrome 22.0.1229.79 32-разрядная на Windows Server 2008 R2 / 7 64-разрядная
$('#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
Насколько я понимаю, ваш вопрос на самом деле не о том, использовать ли JQuery или нет. Скорее: лучше связывать события встроенными в HTML или через прослушиватели событий?
Встроенная привязка устарела. Более того, таким образом вы можете привязать только одну функцию к определенному событию.
Поэтому я рекомендую использовать прослушиватели событий. Таким образом, вы сможете привязать множество функций к одному событию и отсоединить их позже, если это необходимо. Рассмотрим этот чистый код JavaScript:
querySelector('#myDiv').addEventListener('click', function () {
// Some code...
});
Это работает в большинстве современных браузеров.
Однако, если вы уже включили jQuery в свой проект - просто используйте jQuery: .on
или же .click
функция.
Пойдите для этого, поскольку это даст вам и стандарт и производительность.
$('#myDiv').click(function(){
//Some code
});
В качестве второго метода используется простой код JavaScript, который работает быстрее, чем jQuery. Но здесь производительность будет примерно одинаковой.
Вы можете объединить их, используя jQuery, чтобы привязать функцию к клику
<div id="myDiv">Some Content</div>
$('#myDiv').click(divFunction);
function divFunction(){
//some code
}
$('#myDiv').click
лучше, потому что он отделяет код JavaScript от HTML. Нужно стараться, чтобы поведение и структура страницы были разными. Это очень помогает.
Разница в работах. Если вы используете click(), вы можете добавить несколько функций, но если вы используете атрибут, будет выполнена только одна функция - последняя.
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')" )
Если мы говорим о производительности, то в любом случае непосредственное использование всегда быстрее, но с использованием атрибута, вы сможете назначить только одну функцию.
ИМХО, onclick является предпочтительным методом по сравнению с.click, только если выполняются следующие условия:
- на странице много элементов
- только одно событие будет зарегистрировано для события клика
- Вы беспокоитесь о производительности мобильных устройств / времени автономной работы
Я сформировал это мнение из-за того факта, что движки JavaScript на мобильных устройствах в 4-7 раз медленнее, чем их настольные аналоги, созданные в том же поколении. Я ненавижу это, когда посещаю сайт на своем мобильном устройстве и получаю нервную прокрутку, потому что jQuery связывает все события за счет моего пользовательского опыта и времени работы от батареи. Еще один недавний фактор поддержки, хотя это должно касаться только правительственных учреждений;), у нас появилось всплывающее окно IE7 с сообщением о том, что процесс JavaScript занимает много времени... ждать или отменить процесс. Это происходило каждый раз, когда нужно было связать множество элементов с помощью jQuery.
Разделение проблем является ключевым здесь, и поэтому привязка событий является общепринятым методом. Это в основном то, что сказали многие из существующих ответов.
Однако не отбрасывайте идею декларативной разметки слишком быстро. Он имеет свое место, и с такими каркасами, как 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/
Примечание. Основным недостатком второго примера является загрязнение глобального пространства имен. Это можно обойти, используя третью альтернативу, описанную выше, или фреймворки, такие как Angular, и их атрибуты ng-click с автоматической областью действия.
<whatever onclick="doStuff();" onmouseover="in()" onmouseout="out()" />
События onclick, onmouseover, onmouseout и т. д. на самом деле плохо влияют на производительность (в основном в Internet Explorer, иди с цифрой). Если вы кодируете с помощью Visual Studio, когда вы запускаете страницу с ними, каждый из них создаст отдельный блок SCRIPT, занимающий память, и, следовательно, замедляющий производительность.
Не говоря уже о том, что у вас должно быть разделение интересов: JavaScript и макеты должны быть разделены!
Всегда лучше создавать evenHandlers для любого из этих событий, одно событие может захватывать сотни / тысячи элементов вместо создания тысяч отдельных блоков сценариев для каждого из них!
(Кроме того, все, что все остальные говорят.)
Производительность
Здесь уже есть много хороших ответов, авторы иногда упоминают о производительности, но на самом деле это еще никто не исследует, поэтому я сосредоточусь на этом аспекте здесь. Сегодня я провожу тест в Chrome 83.0, Safari 13.1 и Firefox 77.0 для упомянутых решений и, кроме того, нескольких альтернативных решений (некоторые из них упоминались в других ответах).
Полученные результаты
Я сравниваю здесь решения AH, потому что они работают с элементами id
. Я также показываю результаты для решений, использующихclass
(I,J,K) в качестве ссылки.
- решение, основанное на привязке html-встроенного обработчика (B), является быстрым и быстрым для Chrome и самым быстрым для небольшого количества элементов
- решения на основе
getElementById
(C,D) быстрые, и для большого количества элементов самые быстрые в Safari и Firefox - ссылочные решения на основе I,J являются самыми быстрыми для большого количества элементов, поэтому стоит рассмотреть возможность использования
class
вместоid
подход в этом случае - решение на основе jQuery.click (A) самое медленное
Детали
На самом деле было непросто разработать тест производительности для этого вопроса. Я заметил, что для всех протестированных решений скорость запуска событий для 10K div была быстрой, и вручную мне не удалось обнаружить никаких различий между ними (вы можете запустить нижеприведенный фрагмент, чтобы проверить это самостоятельно). Поэтому я сосредотачиваюсь на измерении времени выполнения генерации html и привязки обработчиков событий для двух случаев.
// https://stackru.com/questions/12627443/jquery-click-vs-onclick
let a= [...Array(10000)];
function clean() { test.innerHTML = ''; console.clear() }
function divFunction(el) {
console.log(`clicked on: ${el.id}`);
}
function initA() {
test.innerHTML = a.map((x,i)=> `<div id="myDiv${i}" class="box">${i}</div>`).join``;
a.map((x,i)=> $(`#myDiv${i}`).click(e=> divFunction(e.target)));
}
function initB() {
test.innerHTML = a.map((x,i)=> `<div id="myDiv${i}" class="box" onclick="divFunction(this)">${i}</div>`).join``;
}
function initC() {
test.innerHTML = a.map((x,i)=> `<div id="myDiv${i}" class="box">${i}</div>`).join``;
a.map((x,i)=> document.getElementById(`myDiv${i}`).onclick = e=> divFunction(e.target) );
}
function initD() {
test.innerHTML = a.map((x,i)=> `<div id="myDiv${i}" class="box">${i}</div>`).join``;
a.map((x,i)=> document.getElementById(`myDiv${i}`).addEventListener('click', e=> divFunction(e.target) ));
}
function initE() {
test.innerHTML = a.map((x,i)=> `<div id="myDiv${i}" class="box">${i}</div>`).join``;
a.map((x,i)=> document.querySelector(`#myDiv${i}`).onclick = e=> divFunction(e.target) );
}
function initF() {
test.innerHTML = a.map((x,i)=> `<div id="myDiv${i}" class="box">${i}</div>`).join``;
a.map((x,i)=> document.querySelector(`#myDiv${i}`).addEventListener('click', e=> divFunction(e.target) ));
}
function initG() {
test.innerHTML = a.map((x,i)=> `<div id="myDiv${i}" class="box">${i}</div>`).join``;
a.map((x,i)=> window[`myDiv${i}`].onclick = e=> divFunction(e.target) );
}
function initH() {
test.innerHTML = a.map((x,i)=> `<div id="myDiv${i}" class="box">${i}</div>`).join``;
a.map((x,i)=> window[`myDiv${i}`].addEventListener('click',e=> divFunction(e.target)));
}
function initI() {
test.innerHTML = a.map((x,i)=> `<div id="myDiv${i}" class="box">${i}</div>`).join``;
[...document.querySelectorAll(`.box`)].map(el => el.onclick = e=> divFunction(e.target));
}
function initJ() {
test.innerHTML = a.map((x,i)=> `<div id="myDiv${i}" class="box">${i}</div>`).join``;
[...document.querySelectorAll(`.box`)].map(el => el.addEventListener('click', e=> divFunction(e.target)));
}
function initK() {
test.innerHTML = a.map((x,i)=> `<div id="myDiv${i}" class="box">${i}</div>`).join``;
$(`.box`).click(e=> divFunction(e.target));
}
function measure(f) {
console.time("measure "+f.name);
f();
console.timeEnd("measure "+f.name)
}
#test {
display: flex;
flex-wrap: wrap;
}
.box {
margin: 1px;
height: 10px;
background: red;
font-size: 10px;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>This snippet only presents used solutions. Click to solution button and then click on any red box to trigger its handler</div>
<button onclick="measure(initA)">A</button>
<button onclick="measure(initB)">B</button>
<button onclick="measure(initC)">C</button>
<button onclick="measure(initD)">D</button>
<button onclick="measure(initE)">E</button>
<button onclick="measure(initF)">F</button>
<button onclick="measure(initG)">G</button>
<button onclick="measure(initH)">H</button>
<button onclick="measure(initI)">I</button>
<button onclick="measure(initJ)">J</button>
<button onclick="measure(initK)">K</button>
<button onclick="clean()">Clean</button>
<div id="test"></div>
Вот пример теста для Chrome
Функция Onclick JQuery
$('#selector').click(function(){
//Your Functionality
});
Ни один из них не является лучшим в том, что они могут быть использованы для разных целей. onClick
(должно быть на самом деле onclick
) работает немного лучше, но я очень сомневаюсь, что вы заметите разницу там.
Стоит отметить, что они делают разные вещи: .click
может быть привязан к любой коллекции jQuery, тогда как onclick
должен быть встроен в элементы, к которым вы хотите привязать. Вы также можете привязать только одно событие к использованию onclick
, в то время как .click
позволяет продолжать связывать события.
На мой взгляд, я был бы последовательн в этом и просто использовал .click
везде и держу весь мой код JavaScript вместе и отдельно от HTML.
Не использовать onclick
, Нет никаких причин использовать его, если вы не знаете, что делаете, и, вероятно, не знаете.
В большинстве случаев нативные методы JavaScript являются лучшим выбором по сравнению с jQuery, когда производительность является единственным критерием, но jQuery использует JavaScript и облегчает разработку. Вы можете использовать jQuery, так как он не сильно снижает производительность. В вашем конкретном случае разница в производительности игнорируется.
Первый способ - это предпочесть. Он использует расширенную модель регистрации событий [s], что означает, что вы можете прикрепить несколько обработчиков к одному элементу. Вы можете легко получить доступ к объекту события, и обработчик может жить в любой области видимости функции. Кроме того, он динамический, то есть он может быть вызван в любое время и особенно хорошо подходит для динамически генерируемых элементов. Неважно, используете ли вы jQuery, другую библиотеку или нативные методы напрямую.
Второй метод, использующий встроенные атрибуты, требует большого количества глобальных функций (что приводит к загрязнению пространства имен) и смешивает контент / структуру (HTML) с поведением (JavaScript). Не используйте это.
На ваш вопрос о производительности или стандартах трудно ответить. Два метода просто совершенно разные и делают разные вещи. Первый более могущественный, а второй презираемый (считается плохим стилем).
Первый способ использования onclick
это не jQuery, а просто Javascript, так что вы не получите накладных расходов jQuery. Способ jQuery можно расширить с помощью селекторов, если вам нужно было добавить его к другим элементам, не добавляя обработчик событий для каждого элемента, но, поскольку он у вас есть сейчас, это просто вопрос, нужно ли вам использовать jQuery или нет.
Лично, так как вы используете jQuery, я бы придерживался его, так как он согласован и отсоединяет разметку от скрипта.
Скажем, у вас есть кнопка, вложенная в HTML-элемент, сгенерированный Javascript/Jquery (элементы типа .html() или .innerHTML), тогда вам нужно выбрать самый крайний элемент (родительский) и сделать это
var parentElement = $('#outermostElement')
parentElement.click('button', function(){
console.log('clicked')
})
под самым внешним элементом я имею в виду элемент, который принимает .html(), например
outermostElement.html("<div><button>click<button><div>")
Выполнить JavaScript при нажатии кнопки:
<button onclick="myFunction()">Click me</button>
<script>
function myFunction() {
document.getElementById("demo").innerHTML = "Hello World";
}
</script>