劫持DOM操作

时间:2014-10-23 19:32:51

标签: javascript dom audio

我有问题。我试图在它改变时立即得到音频元素的来源,而不是让它连接到服务器。让我详细说明:服务器只允许一个请求(随机生成的内容网址),这是我想要的,显然我不希望音频元素使用新的源重新加载。我目前正在使用一个变异观察者,但没有幸运地击败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。反正是否真的劫持了属性变化?

1 个答案:

答案 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方法。

以下是使用setAttributehttp://jsfiddle.net/5mLysc9n/1/

的另一个示例
setAttribute

当您修补方法时,您可以保存原始方法功能,这可能很有用。