Mutation Observer 不工作但轮询有效
Mutation Observer not working but Polling works
我在文档开始时将以下代码注入到页面中。
它应该监听视频元素并更改视频元素的 src 属性。
var observer;
function logStuff(node) {
console.log(node.src);
}
function checkAllVideos() {
document.querySelectorAll('video').forEach(function (node) {
logStuff(node);
node.onloadedmetadata = function() {
logStuff(node);
}
});
}
function addObserver() {
function checkNode(node) {
if (node.constructor.name == "HTMLVideoElement") {
logStuff(node);
node.onloadedmetadata = function() {
logStuff(node);
}
}
}
observer = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
mutation.addedNodes.forEach(function (node) {
checkNode(node);
});
});
});
observer.observe(document, {subtree: true, childList: true, characterData: true});
}
addObserver();
checkAllVideos();
上面的轮询版本是:
window.setInterval(function(){
checkAllVideos();
}, 1000);
出于某种奇怪的原因,当注入 https://dailymotion.com
时,变异观察器永远不会工作,但轮询代码会工作..
如果我将突变观察器代码注入到 youtube 的网页中,它工作正常。两个版本的代码都可以在 youtube 上工作,但只有轮询 setInterval
代码在 dailymotion
上工作。有什么想法吗?
我只想在任何 HTMLVideoElement
(<video>
) 更改其 src
属性时收到通知。
为什么突变观察器不起作用?
网页添加视频标签通过:<link rel="alternate" href="https://www.dailymotion.com/services/oembed?url=https%3A%2F%2Fwww.dailymotion.com%2Fvideo%2Fx7ojouk" type="application/json+oembed" title="Surgeon Explains How to Tie Surgical Knots" data-rh="true">
并且 href
包含 iFrame。
而不是观察整个文档。我为每个视频元素创建了一个观察器,它似乎可以工作。
var observer;
var btn = document.getElementById("setsrc");
btn.addEventListener("click", () => {
/* let v = document.getElementsByTagName("video");
v[0].children[0].remove();
v[1].height = "200"; */
let vi = document.createElement("video");
document.body.appendChild(vi);
vi.height = "200";
});
const config = {
attributes: true,
childList: true,
subtree: true
};
function checkAllVideos() {
document.querySelectorAll('video').forEach(observeNode);
observeNode(document.body, config);
}
function observeNode(node) {
const callback = function(mutationsList, observer) {
for (let mutation of mutationsList) {
if (mutation.type === 'childList') {
let addedNodes = mutation.addedNodes;
if (addedNodes && addedNodes.length) {
addedNodes.forEach(n => {
if (n.nodeName === "VIDEO") observeNode(n, config);
});
}
console.log('A child node has been added or removed.');
} else if (mutation.type === 'attributes') {
console.log('The ' + mutation.attributeName + ' attribute was modified.');
}
}
};
// Create an observer instance linked to the callback function
const observer = new MutationObserver(callback);
// Start observing the target node for configured mutations
observer.observe(node, config);
}
checkAllVideos();
<div>
<video width="400" controls id="vid">
<source src="mov_bbb.mp4" type="video/mp4">
<source src="mov_bbb.ogg" type="video/ogg">
Your browser does not support HTML5 video.
</video>
<video width="400" controls id="vid2">
<source src="mov_bbb.mp4" type="video/mp4">
<source src="mov_bbb.ogg" type="video/ogg">
Your browser does not support HTML5 video.
</video>
</div>
<div>
<button id="setsrc">Set</button>
</div>
我在文档开始时将以下代码注入到页面中。 它应该监听视频元素并更改视频元素的 src 属性。
var observer;
function logStuff(node) {
console.log(node.src);
}
function checkAllVideos() {
document.querySelectorAll('video').forEach(function (node) {
logStuff(node);
node.onloadedmetadata = function() {
logStuff(node);
}
});
}
function addObserver() {
function checkNode(node) {
if (node.constructor.name == "HTMLVideoElement") {
logStuff(node);
node.onloadedmetadata = function() {
logStuff(node);
}
}
}
observer = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
mutation.addedNodes.forEach(function (node) {
checkNode(node);
});
});
});
observer.observe(document, {subtree: true, childList: true, characterData: true});
}
addObserver();
checkAllVideos();
上面的轮询版本是:
window.setInterval(function(){
checkAllVideos();
}, 1000);
出于某种奇怪的原因,当注入 https://dailymotion.com
时,变异观察器永远不会工作,但轮询代码会工作..
如果我将突变观察器代码注入到 youtube 的网页中,它工作正常。两个版本的代码都可以在 youtube 上工作,但只有轮询 setInterval
代码在 dailymotion
上工作。有什么想法吗?
我只想在任何 HTMLVideoElement
(<video>
) 更改其 src
属性时收到通知。
为什么突变观察器不起作用?
网页添加视频标签通过:<link rel="alternate" href="https://www.dailymotion.com/services/oembed?url=https%3A%2F%2Fwww.dailymotion.com%2Fvideo%2Fx7ojouk" type="application/json+oembed" title="Surgeon Explains How to Tie Surgical Knots" data-rh="true">
并且 href
包含 iFrame。
而不是观察整个文档。我为每个视频元素创建了一个观察器,它似乎可以工作。
var observer;
var btn = document.getElementById("setsrc");
btn.addEventListener("click", () => {
/* let v = document.getElementsByTagName("video");
v[0].children[0].remove();
v[1].height = "200"; */
let vi = document.createElement("video");
document.body.appendChild(vi);
vi.height = "200";
});
const config = {
attributes: true,
childList: true,
subtree: true
};
function checkAllVideos() {
document.querySelectorAll('video').forEach(observeNode);
observeNode(document.body, config);
}
function observeNode(node) {
const callback = function(mutationsList, observer) {
for (let mutation of mutationsList) {
if (mutation.type === 'childList') {
let addedNodes = mutation.addedNodes;
if (addedNodes && addedNodes.length) {
addedNodes.forEach(n => {
if (n.nodeName === "VIDEO") observeNode(n, config);
});
}
console.log('A child node has been added or removed.');
} else if (mutation.type === 'attributes') {
console.log('The ' + mutation.attributeName + ' attribute was modified.');
}
}
};
// Create an observer instance linked to the callback function
const observer = new MutationObserver(callback);
// Start observing the target node for configured mutations
observer.observe(node, config);
}
checkAllVideos();
<div>
<video width="400" controls id="vid">
<source src="mov_bbb.mp4" type="video/mp4">
<source src="mov_bbb.ogg" type="video/ogg">
Your browser does not support HTML5 video.
</video>
<video width="400" controls id="vid2">
<source src="mov_bbb.mp4" type="video/mp4">
<source src="mov_bbb.ogg" type="video/ogg">
Your browser does not support HTML5 video.
</video>
</div>
<div>
<button id="setsrc">Set</button>
</div>