Chrome 扩展:尽管自动重定向,内容脚本仍然存在

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

背景

我正在尝试创建一个 Chrome 扩展程序,通过显示倒数计时器(下面内容脚本中的

timer
变量)暂时阻止特定网站(例如 YouTube)。在倒计时结束时,会出现几个按钮向用户显示一些选项。我的后台脚本有一个
onUpdated
事件侦听器,并在向我的内容脚本发送消息以插入 HTML 元素(
timer
、按钮等)之前检查网站 URL。

注意事项

  • 如果用户尝试刷新页面,我希望再次触发倒计时,到目前为止它一直在工作。 (即,对于我的

    onUpdated
    事件侦听器,我不检查
    changeInfo.url
    因为刷新时没有 url 更改)。当内容脚本随后被重新注入时,我包括检查以尝试在重新插入之前删除与我的扩展相关的任何 DOM 元素。

  • (不确定是否相关)我使用错误处理来发送消息,因为有时在加载内容脚本之前会有延迟,这需要在我发送消息之前发生。

  • 我已经尝试寻找检测自动重定向(不是用户启动)的方法,但似乎没有任何明显的答案。

问题

虽然我的代码在大多数情况下都有效,但这是迄今为止唯一的例外:当我使用例如此链接打开 YouTube 视频时:https://www.youtube.com/watch?v=ghz71MyzSto&ab_channel=cosmic_drifter_007,YouTube 自动重定向页面并修改 URL 以删除

ab_channel
参数。这会导致在短时间内将多条消息发送到内容脚本。发生这种情况时,应该出现的按钮会响应倒计时值的第一个实例,因此会在可见倒计时(倒计时元素的最终实例)达到零之前弹出。

在这种情况下,最佳行为是在 URL 重定向的短时间内仅触发一次倒计时/扩展体验(我已经看到它可能在其他 chrome 扩展程序上,如 one sec),但我很高兴听取任何建议!

代码

// background.js

chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {    
    if (tab.active && changeInfo.status=="complete" && tab.url.startsWith("https://www.youtube.com") {
            
                // try sending a message to content-script.js to start intervention
                try {
                    const response = chrome.tabs.sendMessage(tab.id, {greeting: "start intervention"});
                }
                catch {
                    setTimeout(() => {
                        const response = chrome.tabs.sendMessage(tab.id, {greeting: "start intervention"});

                    }, 3000); // try sending a message to content-script.js    
                }
                
                // try injecting some CSS code
            
    }
});
// content-script.js

chrome.runtime.onMessage.addListener(
    function(request, sender) {
      if (request.greeting === "start intervention")
        
        // remove existing time management banner, appears to work fine
        if (document.getElementById("time-management-banner")){ 
            document.getElementById("time-management-banner").  textContent = '';
            document.getElementById("time-management-banner").remove();
            console.log("time-management-banner removed");
        }
        else {console.log("time-management-banner not detected")}

        // create and insert all elements 
        banner = document.createElement("div");
        banner.id = 'time-management-banner';
        banner.className = 'time-management';
        banner.innerHTML = "<b>Stop and take a deep breath.</b>";
        document.body.appendChild(banner);

        // remove existing countdown and replace to reset timer, appears to work fine
        if (document.getElementById("time-management-timer")){ 
            document.getElementById("time-management-timer").remove();
            console.log("removed timer element");
        }
        else {console.log("timer element not detected");}
        
        // set up timer
        const timer = document.createElement("div");
        timer.className = "time-management";
        timer.id = "time-management-timer";
        var secondsLeft = 3;
        banner.appendChild(timer);
        
        var downloadTimer = setInterval( 
            () => {

                // when timer runs out
                if (secondsLeft <= 0) {
                    
                    // reset timer
                    clearInterval(downloadTimer);
                    
                    // try removing existing buttons, appears to work fine
                    if (document.getElementsByClassName("time-management-button")){ 
                        const elements = document.getElementsByClassName("time-management-button");
                        while(elements.length>0){
                            elements[0].parentNode.removeChild(elements[0]);
                        }
                    }
                    else {console.log("buttons did not need to be removed")};

                    const proceed_button = document.createElement("button");
                    const exit_button = document.createElement("button");
                    
                    // add button text

    
                    // set class to time-management for CSS and removal
                    proceed_button.className = "time-management-button";
                    exit_button.className = "time-management-button";
                    
                    // set id (truncated)

                    // insert buttons
                    banner.appendChild(proceed_button);
                    banner.appendChild(exit_button);

                    // add button actions (truncated)
                    
                }
                timer.textContent = secondsLeft;
                timer.value = secondsLeft;
                secondsLeft -= 1;

            }, 
            timeout=1000 // interval of 1 second
        )
    
    }
)

我已尝试遵循堆栈溢出指南,但未成功查找类似问题,如果我应该修改我的问题,请告诉我!

javascript google-chrome-extension countdown sendmessage content-script
© www.soinside.com 2019 - 2024. All rights reserved.