Я пытаюсь создать обобщенную процедуру, которая будет воспроизводить звук перед перенаправлением на указанный 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, но я не знаю, какой синтаксис будет использовать его. Любые предложения будут высоко ценится!



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Пока вы мог используете 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 и могу подтвердить, что событие срабатывает при нажатии. Я попробую и вы отредактировать. Спасибо!