我有问题。我试图在它改变时立即得到音频元素的来源,而不是让它连接到服务器。让我详细说明:服务器只允许一个请求(随机生成的内容网址),这是我想要的,显然我不希望音频元素使用新的源重新加载。我目前正在使用一个变异观察者,但没有幸运地击败onclick
的速度(是的,为了不允许任何人直接获取源而涉及复杂的js)。这是代码:
document.getElementsByTagName('audio')[0].setAttribute("autoplay", false);
//not sure if ^^ makes a difference
audioObserver = new MutationObserver(function (mutations) {
window.open(mutations[0].target.src);
//I only listen for one mutation and want to open the url in a new window
audioObserver.disconnect();
//don't listen in order to not cause infinite loop
document.getElementsByTagName('audio')[0].parentNode.removeChild(document.getElementsByTagName('audio')[0]);
//remove the element in order to avoid reloading
});
observerConfig = {
attributes: true,
childList: false,
characterData: false
};
audioObserver.observe(document.getElementsByTagName('audio')[0], observerConfig);
我对任何实现都很满意,即不一定是MutationObserver。反正是否真的劫持了属性变化?
答案 0 :(得分:1)
你是对的MutationObserver
不能做你需要的。这些工作方式,浏览器在脚本运行时收集变异记录,然后在脚本产生时立即将记录传递给观察者。这几乎是异步的。这使得观察者的突变比突变事件更好,它们是同步调度的。当观察者运行时,audio
元素将收到URL并开始加载它。
假设您正在讨论的这个onclick
处理程序设置了元素的.src
属性,您将需要为其定义自定义setter,以便您可以在{{{{}之前拦截该值。 1}}元素的实现处理它。
您可以在JavaScript中定义这样的setter:http://jsfiddle.net/omqdx8d1/
audio
在Chrome中,这样就无法在之后调用原始的setter,但听起来你并不担心。
修改元素属性的另一种方法是使用var el = document.getElementsByTagName('audio')[0];
Object.defineProperty(el, 'src', {
set: function (newSrc) {
console.log('they set src to ' + newSrc);
}
});
方法。如果要拦截它,可以重新定义元素的setAttribute
方法。
以下是使用setAttribute
:http://jsfiddle.net/5mLysc9n/1/
setAttribute
当您修补方法时,您可以保存原始方法功能,这可能很有用。