繁体   English   中英

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

[英]MutationObserver script for Tampermonkey works in Firefox, but not in Chrome

这是在元素出现时保存 state 的脚本(saveMessage 函数),然后使用 MutationObserver 监视元素的 className 的变化并恢复它保存的 state(resetMessage 函数)。 实际上,它在 Firefox 中工作,直到最近的一个补丁(我相信是 v.104),并且在去年一年内没有在 Chrome 中工作(类名为“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节点,因此您不能再将初始 state 保存在节点本身中。 但是,有一个解决方案:在这种情况下,替换元素意味着您会通过删除chat-line__message节点然后添加chat-line__message节点来获得突变。

以下代码保存删除的节点,然后,当添加新的删除消息节点时,恢复新删除的消息节点之前的旧节点并删除该新节点。

设置node.isrestored可以防止循环,因为我们的代码也会触发 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 })
})()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM