Другой вариант - присоединить несколько элементов к одному прослушивателю событий с помощью делегированных обработчиков
Вы можете присоединить родительский слушатель к document
или любому подходящему родительскому узлу. Затем вы можете проверить, было ли событие вызвано соответствующей целью, используя API Element.matches()
или что-нибудь на event.target
document.getElementById("languages").addEventListener('click', function (event) {
if (event.target && event.target.matches("input[type='radio']")) {
// do something here ...
}
});
Это примерно эквивалентно следующему синтаксису jQuery, который использует .on()
для обеспечения делегирования
$("#languages").on("click", "input[type='radio']", function(event) {
// do something here ...
});
Если вы хотите расширить прототип EventTarget.addEventListener()
, вы можете обернуть его собственным методом:
window.EventTarget.prototype.addDelegatedListener = function(type, delegateSelector, listener) {
this.addEventListener(type, function (event) {
if (event.target && event.target.matches(delegateSelector)) {
listener.call(event.target, event)
}
});
}
Тогда используйте вот так:
document.addDelegatedListener("click", "input[type='radio']", function(event) {
// do something here ...
});
Демонстрация в фрагментах стека
// example 1 - regular add event listener
document.getElementById("languages").addEventListener('click', function (event) {
if ( event.target && event.target.matches("input[type='radio']") ) {
console.log(event.target.value)
}
});
// example 2 - reusable delegated listener
window.EventTarget.prototype.addDelegatedListener = function(type, delegateSelector, listener) {
this.addEventListener(type, function (event) {
if (event.target && event.target.matches(delegateSelector)) {
listener.call(event.target, event)
}
});
}
let parent = document.getElementById("weekdays")
parent.addDelegatedListener("click", "input[type='radio']", function(event) {
console.log(this.value)
});
h3 {
margin-top: 20px;
margin-bottom: 10px;
font-size: 1.1em;
}
code {
background: #e9e9e9;
padding: 1px 4px;
border-radius: 3px;
}
label input {
vertical-align: text-top;
}
<h3>Languages <code>addEventListener</code> + <code>Element.matches</code></h3>
<div id="languages">
<label><input type="radio" name="languages" value="HTML"> HTML </label>
<label><input type="radio" name="languages" value="JS"> JS </label>
<label><input type="radio" name="languages" value="CSS"> CSS </label>
</div>
<h3>Weekdays <code>EventTarget.prototype.addDelegatedListener</code></h3>
<div id="weekdays">
<label><input type="radio" name="days" value="Mon"> Mon </label>
<label><input type="radio" name="days" value="Tue"> Tue </label>
<label><input type="radio" name="days" value="Wed"> Wed </label>
</div>