CHROME扩展开发文档之单页面路由变化监控

首先需要在权限里申明需要用到的tab权限

{
    
    
    "permissions": [
        "tabs",
        // "storage",
        // "cookies",
        // "alarms",
        // "scripting",
        // "webRequest",
        // "webRequestBlocking",
        // "*://*/*"
    ]
}

background.js

// 监听页面url变化
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
    
    
    // console.log({changeInfo, tab})
    if (!['complete', 'loading'].includes(changeInfo.status)) return false    
    chrome.tabs.sendMessage(tabId, {
    
    type:'routeUpdate', content: tab}, response => {
    
    
        console.log(response)
    });
});

contentScript.js

// 记录页面路由变化情况
let tabUpdate = 0;
/**
 * 接收bg|popup发给content-script的消息
 * message          object          消息对象
 * sender           object          发送者,含{id: "插件的ID字符串", origin: "null"}
 * sendResponse     function        消息响应,可回复发送者
.*/
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse)
{
    
    
  let {
    
    type, content} = message;

  // console.log('crx: 收到来自bg|popup的消息:');
  // console.log({message, sender});
  if (type === 'routeUpdate') {
    
    
    // 页面路由变化会有两次通知,一次加载时,一次完成时,
    // 判断是更新还是新加载,一律放在complete,
    // 因为重定向会出现多次loading,而complete仅页面加载完成才会触发
    if (content.status == 'loading') {
    
    
      // 如果页面存在重定向会出现只完成一次complete但不止一次的loading,
      // 非特殊情况不在loading判断处理,防止不准
    }
    else if (content.status == 'complete') {
    
    
      if (++tabUpdate > 1) {
    
    
        console.log('complete路由变化' + parseInt(tabUpdate - 1));
      }
      else {
    
    
        console.log('complete新开的页面' + tabUpdate);
      }
    }
  }
  sendResponse('crx: 我是后台,我已收到你的消息:' + JSON.stringify(message));
})

除了利用chrome接口能力,还可以重写history

!!重写history应该是注入到top,而注入到contentScript是监听不到的

  • 重写history
class Dep {
    
                      // 订阅池
        constructor(name){
    
    
            this.id = new Date() //这里简单的运用时间戳做订阅池的ID
            this.subs = []       //该事件下被订阅对象的集合
        }
        defined(){
    
                  // 添加订阅者
            Dep.watch.add(this);
        }
        notify() {
    
                  //通知订阅者有变化
            this.subs.forEach((e, i) => {
    
    
                if(typeof e.update === 'function'){
    
    
                    try {
    
    
                       e.update.apply(e)  //触发订阅者更新函数
                    } catch(err){
    
    
                        console.warr(err)
                    }
                }
            })
        }
        
    }
    Dep.watch = null;

    class Watch {
    
    
        constructor(name, fn){
    
    
            this.name = name;       //订阅消息的名称
            this.id = new Date();   //这里简单的运用时间戳做订阅者的ID
            this.callBack = fn;     //订阅消息发送改变时->订阅者执行的回调函数     
        }
        add(dep) {
    
                      //将订阅者放入dep订阅池
           dep.subs.push(this);
        }
        update() {
    
                      //将订阅者更新方法
            var cb = this.callBack; //赋值为了不改变函数内调用的this
            cb(this.name);          
        }
    }
    var addHistoryMethod = (function(){
    
    
        let historyDep = new Dep();
        return function(name) {
    
    
            if(name === 'historychange'){
    
    
                return function(name, fn){
    
    
                    let event = new Watch(name, fn)
                    Dep.watch = event;
                    historyDep.defined();
                    Dep.watch = null;       //置空供下一个订阅者使用
                }
            } else if(name === 'pushState' || name === 'replaceState') {
    
    
                let method = history[name];
                return function(){
    
    
                    method.apply(history, arguments);
                    historyDep.notify();
                }
            }
            
        }
    }())

    window.addHistoryListener = addHistoryMethod('historychange');
    history.pushState =  addHistoryMethod('pushState');
    history.replaceState =  addHistoryMethod('replaceState');
  • 食用方法
// 使用监听
window.addHistoryListener('history', function(){
    
    
    console.log('窗口的history改变了');
})

猜你喜欢

转载自blog.csdn.net/qq_35606400/article/details/131077872
今日推荐