DOM突变观察者:如何支持DOM3突变事件的一个重要用途

DOM MutationObservers: How to support this one important use of DOM3 Mutation Events?

本文关键字:突变 一个 DOM3 何支持 支持 观察者 DOM 事件      更新时间:2023-09-26

我有时会感到冗长:tl;博士:读粗体字。

贬低突变事件背后的动机是众所周知的;它们在完成许多类型的任务方面的功效是值得怀疑的。

然而,今天,我发现了它们的一种用途,它高度依赖于那些非常不受欢迎的特性。

我将首先提出这个问题,然后提出导致我提出这个问题的原因,因为没有这个问题,这个问题将是荒谬的

是否可以使用新的突变观测器,使VM在变化瞬间停止(就像DOM3突变事件一样),而不是在事后向我报告

基本上,使变异观察者具有性能和"合理"的正是它的异步性,这意味着(似乎必然)扔掉堆栈,将记录变异推到列表中,并在下一次或几次之后将列表交付给合格的观察者。

我所追求的正是DOM3突变事件的叠加痕迹。我真的很希望这能起作用,但基本上,突变事件回调(我被允许编写)将有一个堆栈竞争,这将使我回到创建我正在侦听的元素的实际代码。所以理论上我会写一个突变事件处理程序,像这样:

// NOT in an onload cb
$("div#haystack").on('DOMNodeInserted', function(evt) {
  if (is_needle(evt.target)) {
    report(new Error().stack); // please, Chrome, tell me what code created the needle
  }
});

这给了我一个黄金答案。

看来突变观察者将使提取这些信息变得不可能那么,一旦突变事件完全消除,我该怎么办它们已经被弃用一段时间了。

现在,为了更好地解释真实的实际情况,以及为什么这很重要。

我一直在努力消除我在这里描述的一个错误:我已经构建了一个完整的DOM序列化程序,它可以很好地吐出网页上存在的每个元素,并且在比较它们时,坏页面和工作页面是相同的。我已经测试过了,它非常好。它捕捉到了每一个不同的小东西:无论鼠标悬停在什么地方,最终设置的CSS类都会反映在HTML转储中。如果你搜索页面上任何形式的文本(前提是它不跨越元素),它都会显示出来。所有内联JS(更重要的是,内联JS之间的所有差异)都存在。

然后,我继续验证损坏的页面是否缺少几个事件处理程序。因此,没有一个可点击的项目对悬停或点击做出响应,因此无法在交互式表单上进行有用的工作。这并不是唯一的问题,但它确实充分解释了这种行为。假设DOM在解释行为差异的内联JS中没有差异,那么必须是链接资源的内容或元素的不可见属性(事件处理程序属于此类)导致行为差异的情况。

现在我知道了哪些元素应该有处理程序,但我不知道在这个滑稽的大代码库(大概是:200K行JS都作为一个资源加载,由几行M行Perl服务器端代码组装而成)中,分配事件的代码在哪里。

我尝试过JS方法来观察对象属性的修改,比如这个方法(有很多,但都遵循设置setter和getter的相同原理),它第一次起作用,然后中断应用程序。显然,分配setter和getter会导致系统停止运行。我不清楚如何将这种观察属性分配的方法应用到可以获得命中特定元素的代码点列表的地步。它可能是可行的,但如果我只能发射一次,然后它就会破坏一切,那肯定不行。

因此,用JS观察变量是不可能的。

我可能能够手动插入jQuery本身,这样当我的is_needle()在jQuery处理的元素上成功时,我就会记录jQuery在该元素上执行的所有事件相关函数。这太可怕了,如果我的突变观察者方法失败,我会求助于此。

当然,还有更多的方法可以剥猫皮。我可以在目标元素上使用方便的getEventListeners()来获取其上的事件侦听器函数列表,然后查看那里的代码,搜索代码库以找到这些函数,然后分析代码以找出这些函数插入事件处理程序的所有位置。这其实很简单。

现在我知道了哪些元素应该有处理程序,但我不知道在这个滑稽的大代码库(大概是:200K行JS都作为一个资源加载,由几行M行Perl服务器端代码组装而成)中,分配事件的代码在哪里。

您是否考虑过以某种方式简单地检测.addEventListener函数调用,例如通过调试器断点或修改DOM元素原型以用包装方法替换它?这将是特定于浏览器的,但应该足以满足您的调试需求。

你可能还想试试萤火虫的示踪剂,我想它在夜莺中有售。它基本上记录函数执行,而不需要使用断点或检测代码。