Javascript 围绕现有的MutationObserver使用Tampermonkey插入DOM元素

Javascript 围绕现有的MutationObserver使用Tampermonkey插入DOM元素,javascript,tampermonkey,mutation-observers,Javascript,Tampermonkey,Mutation Observers,我编写了一个Tampermonkey脚本,将一些DOM元素注入到我用于工作的站点中,以使导航更容易。它不再起作用了,因为供应商引入了一个MutationObserver,大概是为了阻止像我这样的人这么做。为什么,我不知道。我没有做任何邪恶的事 我知道这就是所发生的事情,因为我可以看到我的DOM元素短暂地出现然后消失。它们不再出现在DOM树中,站点的JS包含用于MutationObserver的代码: // this is a property of a large object value: f

我编写了一个Tampermonkey脚本,将一些DOM元素注入到我用于工作的站点中,以使导航更容易。它不再起作用了,因为供应商引入了一个MutationObserver,大概是为了阻止像我这样的人这么做。为什么,我不知道。我没有做任何邪恶的事

我知道这就是所发生的事情,因为我可以看到我的DOM元素短暂地出现然后消失。它们不再出现在DOM树中,站点的JS包含用于MutationObserver的代码:

// this is a property of a large object
value: function() {
  var e = this
  if (this._options.shouldContainFocus) {
    this._observer = new MutationObserver(this.handleDOMMutation)
    for (var t = this._contextElement; t && 1 === t.nodeType && "BODY" !== t.tagName;) {
      var n = t.parentElement
      if (n) {
        this._parents.push(n)
        this.muteNode(n)
        Array.prototype.slice.call(n.childNodes).forEach(function(t) {
          e.hideNode(t)
        })
      }
      t = t.parentNode
    }
  }
}

// this is what is called by the MutationObserver
this.handleDOMMutation = function(e) {
  e.forEach(function(e) {
    Array.from(e.addedNodes).forEach(function(e) {
      n.hideNode(e)
    })
    e.removedNodes.forEach(function(e) {
      var t = n._nodes.indexOf(e)
      t >= 0 && n._nodes.splice(t, 1)
    })
  })
}

所以我的问题是。。。如果有的话,我怎样才能摆脱它呢?我所能想到的就是访问一些全球的mutationobserver列表,但据我所知,这似乎并不存在(直到今天我才听说过这个API)。观察员变量不是我可以通过
unsafeWindow
访问的变量,因此我无法调用
disconnect
方法。我已经阅读了有关MutationObserver的文档,但找不到任何帮助。有什么建议吗?

如评论中所述,这里有一种可能的方法可以在加载文档之前覆盖
窗口。MutationObserver
。由于
MutationObserver
被作为构造函数调用,为了使站点脚本不会抛出错误,请确保monkeypatched
MutationObserver
可以作为构造函数调用。然后,由于实例化对象可以调用方法(如
observe
disconnect
),因此您可以返回一个
Proxy
,当访问属性时(如
observator
),该代理返回一个可调用但不执行任何操作的函数。例如:

constdiv=document.querySelector('div');
window.MutationObserver=函数(){
返回新代理({},{get:()=>()=>null})
};
新的MutationObserver(()=>{
log('saw a mutation');
}).observe(div,{childList:true});
div.appendChild(document.createElement('span')).textContent='bar'

foo
该站点的JS包含变异观察者的代码。
你能发布这些代码吗?如果问题可以重现,就有可能找到解决办法。(如果没有代码,这可能是瞎猜)您可能能够在站点上的所有其他脚本之前加载脚本(应该是tampermonkey设置之一,例如在文档开始时运行)。如果是这样的话,您可以用自己的一个来覆盖MutationObserver。我已经添加了代码片段。这是94000行模糊代码的一部分。帕特里克,这是个好主意。但是,难道我的不只是独立于另一个运行吗?理想情况下,我想
断开供应商的
连接,但我不知道如何访问它。我不是说创建自己的实例,即
新建MutationObserver()
。我的意思是像
MutationObserver=function(){}
这样覆盖它,当调用他们的
new MutationObserver()
时,它只会返回一个空实例,而这个实例什么都不做。谢谢。我试过了,控制台显示错误
this.\u observer.observe不是一个指示它工作的函数。我正在Tampermonkey中使用
@runatdocumentstart
,以便尽快运行
unsafeWindow.MutationObserver=function(){}
。但是我的DOM元素仍然被删除!我假设供应商对MutationObserver不可用的浏览器有一个回退选项。那可能是什么?脚本是巨大的,我不知道我会寻找什么。这是非常感谢你提供的代码。不幸的是,我无法让它工作,我正在注入的DOM元素仍在被删除,尽管我可以判断MutationObserver已被替换(请参阅对Patrick Evans的评论回复)。您需要将
window
替换为
unsafeWindow
,或者在未打包的情况下运行您的userscript(即在页面上下文中)通过在标题中声明
@grant none
。在FF中使用第一个方法也需要exportFunction AFAIK,请查看示例。正如我在回复Patrick时所写的评论中所示,我已经在使用
unsafeWindow
——这就是我如何判断
MutationObserver
已被一个无用函数取代的原因。