我在我的Chrome扩展中使用可伸缩的SVG图标。
chrome.browserAction.setIcon({
tabId: tabId,
path: '../icons/' + icon + '/scalable.svg'
});我想要切换一些参数的图标,所以我有视觉反馈。
我意识到,当我非常快地切换图标时,Chrome就会搞砸,而且经常会看到错误的图标。我在代码中添加了console.log打印,以确保我正确地切换图标,并且我看到我的代码没有错误。
看起来Chrome异步执行这种图标请求的更改,而SVG到像素的转换有时比平常要长一些。这会导致执行错误的顺序。
例如,如果我将图标从A切换到B,然后切换到C,然后切换到D,.最后,我可能会看到C,尽管最后的更改请求是将其转换为D。
对如何解决这个烦人的问题有什么想法吗?
发布于 2021-02-02 20:39:56
使用Promise
setIcon )链接对API的调用,自己创建一个imageData缓存,而不是path,因为API每次都会重新读取源图标并重新创建imageData.。
下面是一个没有经过测试的通用示例:
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;
});
}https://stackoverflow.com/questions/66016918
复制相似问题