替换 history.pushState 以发送事件(获取 Ilegal 调用错误)

Replacing history.pushState to send events (getting Ilegal invocation error)

提问人:Rafael Costa 提问时间:7/14/2023 更新时间:7/14/2023 访问量:37

问:

我有一个库,它被添加到一个SPA项目中,它使用router.push(最终将调用window.history.pushState)来更改url。

但是,我需要我的库能够侦听这些更改,但是由于它是一个外部 SPA,我的库无法知道何时进行这些更改,因为 pushState 不会触发任何事件。

所以,我认为一个好方法是用我的函数替换window.history.pushState,这样我就可以在触发事件后发送事件。

这是我所做的:

const pushState = window.history.pushState;

window.history.pushState = (state, unused, url) => {
    // just some code to trigger an event I can later intercept:
    const event = new Event("someEvent"); 
    window.dispatchEvent(event);

    // calls the original function, so that everything could be transparent
    return pushState(state, unused, url);
};

但是,我不断收到错误,无法弄清楚我做错了什么。TypeError: Illegal invocation at window.history.pushState

谁能帮我?

JavaScript 类型错误 pushstate html5 历史

评论


答:

1赞 jagmitg 7/14/2023 #1

当方法从其原始上下文中取出并在其他地方使用时,就会发生非法调用。这是一本好

在您的例子中是 的方法,因此它期望始终在 的上下文中被调用。pushStatewindow.historywindow.history

这是你如何做到的:

const pushState = window.history.pushState;

window.history.pushState = function(state, unused, url) {
    const event = new Event("someEvent"); 
    window.dispatchEvent(event);
    return pushState.call(window.history, state, unused, url);
};
1赞 Unmitigated 7/14/2023 #2

您可以使用 Function#bind 为函数设置正确的值。this

const pushState = history.pushState.bind(history);
// the rest of the code remains the same...