检测选项卡重复事件

时间:2017-05-29 07:07:35

标签: javascript google-chrome google-chrome-extension javascript-events chromium

我正在开发Chrome扩展程序;

我需要检测标签何时重复,我正在寻找像onduplicate.addListener()这样的标签检测事件?

Chrome扩展程序API可以实现吗?

2 个答案:

答案 0 :(得分:2)

这是最接近的实施:

const newTabsId = new Set();

// Observe all new tabs with opener ID
chrome.tabs.onCreated.addListener(tab => {
    if(tab.openerTabId) {
        newTabsId.add(tab.id);
    }
});

// Waiting for a new tab completeness
chrome.tabs.onUpdated.addListener((tabId, changes, tab) => {
    if(newTabsId.has(tabId) && changes.status === 'complete') { 
        if(!tab.openerTabId) {
            return;
        }
        // Retrieve opener (original) tab
        getTabById(tab.openerTabId)
            .then(originalTab => {
                if(
                    originalTab.url === tab.url &&          // original and new tab should have same URL
                    originalTab.index + 1 === tab.index &&  // new tab should have next index
                    tab.active && tab.selected              // new tab should be active and selected
                                                            // also we may compare scroll from top, but for that we need to use content-script
                ) {
                    console.log('Duplicate:', tab);
                }
            });
        // Remove this tab from observable list
        newTabsId.delete(tabId);
    }
});

// Syntax sugar
function getTabById(id) {
    return new Promise((resolve, reject) => {
        chrome.tabs.get(id, resolve);
    });
}

// Cleanup memory: remove from observables if tab has been closed
chrome.tabs.onRemoved.addListener(tabId => {
    newTabsId.delete(tabId);
});

编辑1 :但是,现在没有明确的解决方案来检测真正的重复

答案 1 :(得分:1)

标签重复会保留页面的sessionStorage,因此只需在每个页面的内容脚本中存储一些唯一变量,并检查它是否出现在内容脚本的开头。

清单:

"content_scripts": [{
  "matches": ["<all_urls>"],
  "run_at": "document_start",
  "js": ["content.js"]
}],

内容脚本:

if (sessionStorage[chrome.runtime.id]) {
  chrome.runtime.sendMessage({
    action: 'checkDup',
    tabId: Number(sessionStorage[chrome.runtime.id]),
  }, isDupe => {
    console.log(isDupe);
  });
} else {
  chrome.runtime.sendMessage({
    action: 'getTabId'
  }, tabId => {
    sessionStorage[chrome.runtime.id] = tabId;
  });
}

背景/事件脚本:

chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
  switch (msg.action) {
    case 'getTabId':
      sendResponse(sender.tab.id);
      return;
    case 'checkDup':
      chrome.tabs.get(msg.tabId, tab => {
        if (tab 
        && tab.index == sender.tab.index - 1 
        && tab.url == sender.tab.url) {
          sendResponse(true);
          console.log('Tab duplicated: ', tab, '->', sender.tab);
        }
      });
      return true; // keep the message channel open
  }
});