首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有SVG图标的Chrome扩展(chrome.browserAction.setIcon)

问带有SVG图标的Chrome扩展(chrome.browserAction.setIcon)
EN

Stack Overflow用户
提问于 2021-02-02 20:09:41
回答 1查看 522关注 0票数 0

我在我的Chrome扩展中使用可伸缩的SVG图标。

代码语言:javascript
复制
chrome.browserAction.setIcon({
  tabId: tabId,
  path: '../icons/' + icon + '/scalable.svg'
});

我想要切换一些参数的图标,所以我有视觉反馈。

我意识到,当我非常快地切换图标时,Chrome就会搞砸,而且经常会看到错误的图标。我在代码中添加了console.log打印,以确保我正确地切换图标,并且我看到我的代码没有错误。

看起来Chrome异步执行这种图标请求的更改,而SVG到像素的转换有时比平常要长一些。这会导致执行错误的顺序。

例如,如果我将图标从A切换到B,然后切换到C,然后切换到D,.最后,我可能会看到C,尽管最后的更改请求是将其转换为D。

对如何解决这个烦人的问题有什么想法吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-02-02 20:39:56

使用Promise

  • If (经常调用的setIcon )链接对API的调用,自己创建一个imageData缓存,而不是path,因为API每次都会重新读取源图标并重新创建imageData.

。

下面是一个没有经过测试的通用示例:

代码语言:javascript
复制
const queue = {};
const cache = {};
// auto-clean the queue so it doesn't grow infinitely
chrome.tabs.onRemoved.addListener(tabId => delete queue[tabId]);

async function setIcon(tabId, icon) {
  const url = '../icons/' + icon + '/scalable.svg';
  const imageData = await (cache[url] || (cache[url] = loadImageData(url)));
  queue[tabId] = (queue[tabId] || Promise.resolve()).then(() =>
    new Promise(resolve =>
      chrome.browserAction.setIcon({tabId, imageData}, resolve)));
}

function loadImageData(url) {
  return new Promise((resolve, reject) => {
    const data = {};
    const img = new Image();
    img.src = url;
    img.onload = () => {
      for (const size of [16, 32]) {
        const canvas = document.createElement('canvas');
        document.documentElement.appendChild(canvas);
        canvas.width = canvas.height = size;
        const ctx = canvas.getContext('2d');
        ctx.drawImage(img, 0, 0);
        data[size] = ctx.getImageData(0, 0, size, size);
        canvas.remove();
      }
      resolve(data);
    };
    img.onerror = reject;
  });
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66016918

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档