DOM MutationObservers:如何支持DOM3 Mutation事件的这一重要用途?

时间:2013-07-18 18:41:53

标签: javascript html5 dom mutation-observers

我有时会罗嗦:tl;博士:阅读粗体文字。

贬低突变事件背后的动机是很好理解的;他们在完成许多类型任务方面的功效值得怀疑。

然而,今天,我发现它们的用途高度依赖于那些非常相同的不良属性。

我将首先提出问题,然后提出引导我提出问题的原因,因为如果没有它,这个问题将是荒谬的。

是否有可能以一种我们可以让VM在变化瞬间停止的方式使用新的Mutation Observers(就像DOM3 Mutation Events那样),而不是在事后报告给我?

基本上,使Mutation Observer具有高效性和“合理性”的是它的异步性,这意味着(必然,似乎)丢弃堆栈,将记录突变推送到列表,并将列表提供给合格的观察者在下一个刻度或几个刻度之后。

我所追求的正是DOM3 Mutation Event的堆栈跟踪。我真的希望这会有效,但基本上Mutation Event回调(我可以写)会有一个堆栈跟踪,它将引导我回到创建我正在听的元素的实际代码对于。所以理论上我会编写一个像这样的Mutation Event处理程序:

// 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
  }
});

这给了我更好的答案。

Mutation Observers似乎无法提取这些信息。 一旦突变事件完全被取消,我该怎么做?他们已经被弃用了一段时间。

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

我一直试图杀死一个I describe here的错误:我已经构建了一个完整的DOM序列化程序,可以很好地将网页上存在的每个元素都吐出来,并比较它们,破坏的页面和工作页面是相同的。我测试了这个,非常好。它捕获了每个不同的小东西:无论我的鼠标碰巧结束了什么样的东西,因此设置的CSS类将反映在HTML转储中。如果您搜索它,则会显示页面上任何表单的任何文本(前提是它不跨越元素)。所有内联JS(更重要的是,内联JS之间的所有差异)都存在。

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

现在我知道哪些元素应该有处理程序,但我不知道在可笑的大代码库中的位置(ballpark:所有作为一个资源加载的200K JS的行,由几行M服务器代码组装而成)是分配事件的代码。

我已经尝试过JS方法来观察对象属性的修改,例如this one(有很多,但都按照设置setter和getter的相同原理工作),这是第一次工作,然后是之后打破应用。显然分配setter和getter会导致系统停止运行。我不清楚我如何能够采用这种方法来观察属性分配,以便获得一个能够获得特定元素的代码点列表。它可能是可行的,但如果我只能一次,那肯定不行,并且此后它会破坏所有内容。

所以用JS观察变量是不合适的。

我或许可以手动设置jQuery本身,这样当我的is_needle()成功处理jQuery处理的元素时,我会记录jQuery对该元素执行的所有与事件相关的函数。这是可怕的,如果我的Mutation Observer方法失败,我将诉诸于此。

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

1 个答案:

答案 0 :(得分:0)

  

现在我知道哪些元素应该有处理程序,但我不知道在可笑的大代码库中的位置(ballpark:所有作为一个资源加载的200K JS的行,由几行M服务器代码组装而成)是分配事件的代码。

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

您也可以尝试使用firefox的示踪器,我认为它可以在夜间使用。它基本上记录了函数执行,而无需使用断点或检测代码。