You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何DOMContentLoaded在Vivaldi论坛站内跳转时不触发?

为什么DOMContentLoaded不会在Vivaldi论坛内跳转时触发?

嗨,这个问题其实挺常见的——现在不少现代论坛(包括Vivaldi这个)都用上了异步页面加载技术(比如PJAX或者类SPA模式),而不是每次页面跳转都重新加载整个HTML文档。

你得先搞懂DOMContentLoaded的触发逻辑:它只会在整个初始HTML文档被完全加载并解析完成时触发,哪怕样式表、图片还没加载完也没关系,但前提是整个文档是从头加载的。而当你在论坛内跳转时,网站根本没有重新加载整个页面,只是用JS异步替换了页面里的核心内容(比如帖子内容、列表区域),同时通过HTML5的History API修改了地址栏的URL。这种情况下,整个文档的DOM树并没有被重新构建,DOMContentLoaded自然不会再次触发。

那怎么解决这个问题?给你几个实用的方案:

方案1:监听PJAX专属事件

很多用PJAX的网站会抛出特定的自定义事件,比如pjax:complete或者pjax:success,直接监听这些事件就能捕获页面切换:

//==UserScript==
//@include https://forum.vivaldi.net/*
//==/UserScript==
(function () {
    // 统一处理页面加载逻辑
    function handlePageLoad() {
        alert('A new page is loaded');
    }

    // 处理初始页面加载
    window.addEventListener('DOMContentLoaded', handlePageLoad);

    // 监听PJAX跳转完成事件
    document.addEventListener('pjax:complete', handlePageLoad);
})();

方案2:监听History状态变化

如果网站没暴露PJAX事件,你可以通过重写pushState/replaceState方法,再结合popstate事件,捕获所有URL变化:

//==UserScript==
//@include https://forum.vivaldi.net/*
//==/UserScript==
(function () {
    function handlePageLoad() {
        alert('A new page is loaded');
    }

    // 初始加载触发
    window.addEventListener('DOMContentLoaded', handlePageLoad);

    // 重写pushState,捕获主动跳转
    const originalPushState = history.pushState;
    history.pushState = function(...args) {
        originalPushState.apply(this, args);
        handlePageLoad();
    };

    // 重写replaceState,捕获状态替换
    const originalReplaceState = history.replaceState;
    history.replaceState = function(...args) {
        originalReplaceState.apply(this, args);
        handlePageLoad();
    };

    // 监听浏览器前进后退操作
    window.addEventListener('popstate', handlePageLoad);
})();

方案3:用MutationObserver监测内容变化

如果上面两种方法都不生效,你可以用MutationObserver盯着页面的核心内容区域,一旦内容发生显著变化就触发逻辑:

//==UserScript==
//@include https://forum.vivaldi.net/*
//==/UserScript==
(function () {
    function handlePageLoad() {
        alert('A new page is loaded');
    }

    window.addEventListener('DOMContentLoaded', function() {
        handlePageLoad();

        // 找到论坛每次跳转都会替换的核心容器(需自己用开发者工具确认选择器)
        const targetNode = document.querySelector('.topic-content'); // 示例选择器,替换为实际容器
        if (targetNode) {
            const observer = new MutationObserver(function() {
                // 核心内容变化时触发
                handlePageLoad();
            });

            // 监听子节点变化和子树变化
            observer.observe(targetNode, { childList: true, subtree: true });
        }
    });
})();

注意:方案3里的选择器需要你自己用浏览器开发者工具查看Vivaldi论坛的实际DOM结构,找到每次跳转都会更新的核心容器,替换掉示例里的.topic-content。

内容的提问来源于stack exchange,提问作者user13112502

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 07:02:33