我正在尝试创建一个通用例程,该例程将在重定向到链接的指定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类匹配playsound的元素,因为现在它仅适用于第一个。
我假设使用querySelectorAll,并且需要某种forEach,但是我不知道使用它的语法是什么。任何建议将不胜感激!
答案 0 :(得分: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
返回,为了使网站访问者能够可靠地工作,您需要使用polyfill ,即Array
方法的In-Memory Cache
)