Tampermonkey的MutationObserver脚本适用于Firefox,但不适用于Chrome



这是一个脚本,它可以在元素出现时保存元素的状态(saveMessage函数(,然后使用MutationObserver监视元素的className中的更改并恢复其保存的状态(resetMessage函数(。事实上,在最近的一个补丁(我相信是第104版(之前,它一直在Firefox中运行,并且至少有一年没有在Chrome中运行(className为"chat-line__message--deleted notice"的元素文本不会恢复,只是什么都没发生(。现在它在FF中似乎什么都不做,但因为它在FF和Chrome中同时工作,我认为它一定是与标准有一些非常小的偏差或类似的东西。你知道它怎么了吗?

// ==UserScript==
// @name         Twitch: <message deleted>
// @namespace    https://greasyfork.org/users/221926
// @version      1.3
// @description  show deleted messages in twitch chat
// @match      https://www.twitch.tv/*
// @grant        none
// @run-at       document-end
// ==/UserScript==
(function () {
'use strict'
function saveMessage (el) {
if (el.initialChildNodes) return
el.initialChildNodes = Array.from(el.childNodes)
}
function resetMessage (el) {
while (el.initialChildNodes == null) { el = el.parentNode }
while (el.lastChild) { el.removeChild(el.lastChild) }
el.initialChildNodes.forEach(childNode => el.appendChild(childNode))
el = el.closest('.chat-line__message')
el.style.backgroundColor = 'rgba(255, 0, 0, .1)'
el.style.boxShadow = 'inset 4px 0 0 0 rgba(255, 0, 0, .4)'
}
new MutationObserver(mutationList => {
mutationList.forEach(mutation => {
Array.from(mutation.addedNodes).forEach(el => {
switch (el.className) {
case 'chat-line__message': saveMessage(el.querySelector('.chat-line__username-container').parentNode); break
case 'chat-line__message--deleted-notice': resetMessage(el); break
}
})
})
}).observe(document.body, { childList: true, subtree: true, characterData: true })
})()

看起来Twitch现在替换了整个.chat-line__message节点,因此您无法再将初始状态保存在节点本身。然而,有一个解决方案:在这种情况下,替换元素意味着删除chat-line__message节点,然后添加chat-line__message节点,从而获得突变。

以下代码保存已删除的节点,然后,当添加新的已删除消息节点时,恢复新的

已删除的消息设置node.isrestored可以防止循环,因为我们的代码als会触发MutationObserver。

(function () {
'use strict'
var previousMutationRemoved;
function resetMessage (el) {
if (previousMutationRemoved == null) return;
previousMutationRemoved.style.backgroundColor = 'rgba(255, 0, 0, .1)';
previousMutationRemoved.style.boxShadow = 'inset 4px 0 0 0 rgba(255, 0, 0, .4)';
previousMutationRemoved.isrestored = 'true';
el.parentNode.insertBefore(previousMutationRemoved.cloneNode(true), el);
previousMutationRemoved = null;
el.isrestored = 'true';
el.parentNode.removeChild(el);
}
new MutationObserver(mutationList => {
mutationList.forEach(mutation => {
Array.from(mutation.removedNodes).forEach(node => {
if (node.nodeType == Node.ELEMENT_NODE) {
if (node.className == 'chat-line__message' && node.isrestored != 'true') {
previousMutationRemoved = node;
}
}
});
Array.from(mutation.addedNodes).forEach(node => {
if (node.nodeType == Node.ELEMENT_NODE) {
if (node.className == 'chat-line__message' && node.isrestored != 'true') {
if(node.querySelector(".chat-line__message--deleted-notice")) {
resetMessage(node);
}
}
}
})
});
previousMutationRemoved = null;
}).observe(document.body, { childList: true, subtree: true, characterData: true })
})()

最新更新