Изменение querySelector для применения ко всем элементам страницы (querySelectorAll)

Я пытаюсь создать обобщенную процедуру, которая будет воспроизводить звук перед перенаправлением на указанный href ссылки. Я стараюсь сделать это как можно более динамичным, чтобы не добавлять события onclick к каждой ссылке вручную и т. д.

Из другого кода в stackoverflow и других местах мне удалось найти почти именно то, что я ищу.

    document.querySelector('.playsound').onclick = function (evt) {
        evt = evt || window.event;

        playThenRedirectTo('sndButton', this.href);

        // prevent the link from being followed, until we want to later on
        if (evt.preventDefault) {
            evt.preventDefault();
        } else {
            evt.returnValue = false;
        }
    }

    function play_single_sound(target) {
        document.getElementById(target).play();
    }
    function newPage(url) {
        location.href = url;
    }
    function playThenRedirectTo(audioTarget, url) {
        var time = 0;

        play_single_sound(audioTarget);

        setInterval(function () {
            var end = document.getElementById(audioTarget).played.end(0);
            if (end > time) {
                time = end;
            } else {
                newPage(url);
            }
        }, 250);
    }

Это работает для первого элемента на странице. Звуковой файл воспроизводится до перенаправления. Однако я не уверен, как это применить ко всем элементам с воспроизведением сопоставления классов css, поскольку сейчас это относится только к первому.

Я предполагаю, что потребуется querySelectorAll и какой-то forEach, но я не знаю, какой синтаксис будет использовать его. Любые предложения будут высоко ценится!

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
0
79
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Пока вы мог используете querySelectorAll для добавления слушателя к каждому <a> на странице, вы можете вместо этого рассмотреть делегирование событий: добавьте в документ слушателя кликов не замужем, и при нажатии на что-то проверьте, является ли цель a. Если да, позвоните в playThenRedirectTo:

document.addEventListener('click', (e) => {
  if (!e.target.matches('a')) return;
  // if you only want `.playSound` `a`s to trigger this behavior, instead use
  // if (!e.target.matches('a.playSound')) return;

  playThenRedirectTo('sndButton', e.target.href);
  if (e.preventDefault) {
    e.preventDefault();
  } else {
    e.returnValue = false;
  }
});

Версия querySelectorAll включает использование forEach для перебора всех элементов и присоединение слушателя к каждому:

Array.prototype.forEach.call(
  document.querySelectorAll('a.playsound'), // or whatever selector you want
  playsound => playsound.onclick = e => {
    playThenRedirectTo('sndButton', playsound.href);
    if (e.preventDefault) {
      e.preventDefault();
    } else {
      e.returnValue = false;
    }
  }
);

(хотя в более новых браузерах вы можете forEach непосредственно через NodeList, например, возвращенный querySelectorAll, чтобы это работало надежно для посетителей веб-сайта, вам понадобится полифилл, таким образом, call метода Array)

Здравствуйте, CertainPerformance, Спасибо за быстрый ответ. Мне нравится ваше первое предложенное решение, определенно кажется более элегантным. При этом, когда я его реализовал, похоже, что звуковой файл не воспроизводится. Я добавил строку console.info и могу подтвердить, что событие срабатывает при нажатии. Я попробую и вы отредактировать. Спасибо!

Booyah 15.12.2018 11:34

По какой-то причине первый метод не работает, а второй работает. Спасибо за вашу помощь

Booyah 15.12.2018 17:43

Другие вопросы по теме