劫持addEventListener会导致在向HTMLUnknownElement添加react-invokeguardedcallback监听器时出现过多的递归

问题描述 投票:0回答:1

我有一个用例,我想监视添加的事件侦听器。我在这里找到了一种对我有用的方法:https://stackoverflow.com/a/6434924

这段代码似乎在很多情况下都有效,但是,当在包含 React 应用程序的页面上使用时,它似乎会抛出

InternalError: too much recursion
异常。

最简单的再现器如下所示:

Node.prototype.realAddEventListener = Node.prototype.addEventListener;

Node.prototype.addEventListener = function(a,b,c){
    this.realAddEventListener(a,b,c);
}
在错误发生之前打印

this

a
b
 会产生:

this = [object HTMLUnknownElement] a = react-invokeguardedcallback b = function callCallback() { // We immediately remove the callback from event listeners so that // nested `invokeGuardedCallback` calls do not clash. Otherwise, a // nested call would trigger the fake event handlers of any call higher // in the stack. fakeNode.removeEventListener(evtType, callCallback, false); // We check for window.hasOwnProperty('event') to prevent the // window.event assignment in both IE <= 10 as they throw an error // "Member not found" in strict mode, and in Firefox which does not // support window.event. if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) { window.event = windowEvent; } func.apply(context, funcArgs); didError = false; }
使用上面的函数处理程序向 

react-invokeguardedcallback

 上的 HTMLUnknownElement 添加侦听器会导致我被劫持的 
addEventListener
 递归吗?

javascript reactjs recursion prototype
1个回答
0
投票
修好了。

事实证明

realAddEventListener

 并未分配给原始 
addEventListener
 实现。相反,我对 addEventListener 的重新分配首先发生,然后 
realAddEventListener
 被分配给我被劫持的函数,导致无限递归。

修复方法是通过 Promises 确保事件的顺序:

const handlerMagic = new Promise((resolve)=>{ Node.prototype.realAddEventListener = Node.prototype.addEventListener; resolve() }).then(_=>{ Node.prototype.addEventListener = function(a,b,c){ this.realAddEventListener(a,b,c) } })
现在工作正常。

© www.soinside.com 2019 - 2024. All rights reserved.