我在 chrome 91 中的选项卡更新/激活/焦点事件上收到错误“现在无法编辑选项卡(用户可能正在拖动选项卡)”

IT技术 javascript google-chrome-extension
2021-02-15 19:22:04

在最近的 Chrome 更新之后,当我尝试使用 chrome.tabs API 时,我的扩展程序开始触发“Unchecked runtime.lastError: Tabs cannot be edit right (user may be drag a tab)”。目前还没有关于这个问题的太多信息,但我相信这是一个浏览器错误。与此同时,我的扩展程序导致 chrome 标签的切换速度明显变慢,以前是这样。现在需要几秒钟来更改选项卡。所以我正在寻找一种解决方法。

任何想法如何解决这一问题?

5个回答

到目前为止,我找到的唯一解决方案是将我的处理程序置于这样的超时状态:

chrome.tabs.onActivated.addListener((activeInfo) => {
        setTimeout(() => {
           // The old listener handler moves here
        }, 100);
    });

但一定有更好的方法,对吧?

嗨@Sergey 你找到更好的解决方案了吗?我已经能够用这个解决方案解决这个问题。但是,我认为这不是一个好习惯。
2021-04-25 19:22:04

您仍然会收到错误,但至少它会起作用

chrome.tabs.onActivated.addListener(function(activeInfo) {getActivatedTab();});
function getActivatedTab(){
    chrome.tabs.query({'active': true, 'lastFocusedWindow': true}, function (tabs) {
        try{
            if(tabs[0]!=undefined){
            
                console.log(tabs[0].url);   
            }
        }
        catch(err){
            setTimeout(function() {
            getActivatedTab();
            },100);
        }
    })
}
效果很好,谢谢...提交了我的扩展并修复了:D
2021-04-23 19:22:04

在 chrome.tabs.onActivated.addListener 之外创建单独的函数。这种方式对我有用。

function insertScript(tab) {
  chrome.tabs.get(tab.tabId, function (info) {
    console.log(info);
   });
}
chrome.tabs.onActivated.addListener(function (tab) {
   setTimeout(function () {
     insertScript(tab);
    }, 500);
});

正如@wOxxOm 所指出的,这是Chrome91 中的一个错误

如果您对例如进行大量调用,则建议使用此补丁 xchrome.tabs.query

const ChromeWrapper = {
  chromeTabsQuery: function (params, callback) {
    chrome.tabs.query(params, tabs => {
      if (chrome.runtime.lastError) {
        setTimeout(function () {
          //console.warn("Patch for xchrome.tabs.query (Chrome 91).");
          ChromeWrapper.chromeTabsQuery(params, callback)
        }, 100); // arbitrary delay
      } else {
        callback(tabs)
      }
    })
  }
}

然后,只需替换的实例

xchrome.tabs.query(...

和:

ChromeWrapper.chromeTabsQuery(...

...好吧,除了setTimeout,我没有更好的解决方案,因为我真的没有看到标签完成后发布的消息/事件在哪里,所以我所做的也是添加一个setTimeout来做一些“试验”和错误”。

但是我的做法是覆盖原来的,chrome.tabs.get这样我们就可以按照预期的方式使用它。(当他们最终修复它时,很容易删除这个片段)

这是我的代码,干杯

    chrome.tabs.get = function () {
        const orig_get = chrome.tabs.get.bind(chrome.tabs);
        return async function (tabId) {
            return new Promise(
                resolve => {
                    var tryGet = () => {
                        orig_get(tabId)
                        .then(resolve)
                        .catch(() => {
                            // console.log("retry get");
                            setTimeout(() => {
                                tryGet(tabId);
                            }, 50);
                        })
                    };
                    tryGet();
                }
            )
        }
    }();