#javascript #event-handling #dom-events #addeventlistener #event-delegation
Вопрос:
Я пытаюсь использовать одну и ту же функцию для изменения цвета трех разных дивов, но это не работает. Пожалуйста, ознакомьтесь с приведенным ниже кодом:
const hours=document.getElementById('hours');
const minutes=document.getElementById('minutes');
const seconds=document.getElementById('seconds');
hours.addEventListener('click',changeColor);
minutes.addEventListener('click', changeColor);
seconds.addEventListener('click', changeColor);
function changeColor(obj){
if(obj.style.backgroundColor==='seashell'){
obj.style.backgroundColor='red';
} else{
obj.style.backgroundColor='seashell';
}
}
Комментарии:
1. кстати, используемая техника-это простая прямая обработка событий. Делегирование событий отличается от первого. … Дэвид Уолш :: Как работает Делегирование Событий JavaScript … javascript.info :: Делегирование мероприятий … jQuery :: Понимание делегирования событий
Ответ №1:
Функции обработчика (обратного вызова) зарегистрированного прослушивателя событий передается event
объект. Если кто-то хочет получить доступ к элементу, в котором был зарегистрирован слушатель, то следует использовать свойство event
‘s currentTarget
, а не target
, поскольку последнее не должно быть идентичным первому.
Пример обработки событий операционной системы …
function changeColor(evt) {
const obj = evt.currentTarget;
const objStyle = obj.style;
const bgColor = (objStyle.backgroundColor === 'seashell')
? 'red'
: 'seashell';
objStyle.backgroundColor = bgColor;
}
document
.querySelectorAll('[type="number"]')
.forEach(elmNode =>
elmNode.addEventListener('click' ,changeColor)
);
<input id="hours" type="number" min="0" max="23" />
<input id="minutes" type="number" min="0" max="59" />
<input id="seconds" type="number" min="0" max="59" />
… превратился в пример на основе делегирования событий …
function handleColorChange(evt) {
const target = evt.target;
if (target) {
if (
target.classList.contains('label') ||
(target.tagName.toUpperCase() === 'LABEL')
) {
// evt.stopImmediatePropagation();
// evt.stopPropagation();
// prevent input field event delegation.
evt.preventDefault();
// prevents that a click on the label appears
// to always set a red background color due to
// handling this event twice once for the label
// and a second time for the number input field.
}
const inputRoot = evt.target?.closest('label');
if (inputRoot) {
const inputNode =
inputRoot.querySelector('[type="number"]');
const inputStyle = inputNode?.style;
if (inputStyle) {
const bgColor = (inputStyle.backgroundColor === 'seashell')
? 'red'
: 'seashell';
inputStyle.backgroundColor = bgColor;
}
}
}
console.log('evt.target ... ', target);
}
document
.querySelector('form')
.addEventListener('click' , handleColorChange/*, true*/);
body { margin: -2px 0 0 0; }
label { padding-left: 8px; padding-right: 8px,}
.as-console-wrapper { max-height: 140px!important; }
<form>
<fieldset>
<legend>Time Settings</legend>
<label>
<span class="label">
hours
</span>
<input name="hours" type="number" min="0" max="23" />
</label>
<label>
<span class="label">
minutes
</span>
<input name="minutes" type="number" min="0" max="59" />
</label>
<label>
<span class="label">
seconds
</span>
<input name="seconds" type="number" min="0" max="59" />
</label>
</fieldset>
</form>
Комментарии:
1. Большое спасибо
2. @Джорджетомех … Я добавил второй, на этот раз основанный на делегировании событий, пример кода к своему ответу, чтобы показать разницу между обоими методами.
3. спасибо вам за ваше дополнение. Это действительно полезно.
Ответ №2:
Аргумент прослушивателя событий является Event
объектом, а не целью события. Используйте event.target
, чтобы получить элемент, на который был нажат.
function changeColor(event) {
let obj = event.target;
if (obj.style.backgroundColor === 'seashell') {
obj.style.backgroundColor = 'red';
} else {
obj.style.backgroundColor = 'seashell';
}
}
Комментарии:
1. Спасибо вам за ваш ответ. Что делать, если мне нужно передать больше, чем параметр в функции changeColor, как я буду вызывать ее в addEventListener.
2. Используйте анонимную функцию:
addEventListener("click", function(event) { changeColor(event, "another parameter"); })