Как я мог бы применить правильную обработку событий или даже делегирование событий к моему примеру кода?

#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"); })