我试图创建一个基于所选内容的Chrome浏览器右键菜单项。 我发现这个几个问题#2,和所有的人的答案是:使用内容脚本以“鼠标按下”监听器,着眼于当前的选择,并创建上下文菜单。
我实现了这一点,但它并不总是工作。 有时候,所有日志消息说,上下文菜单被修改,因为我想,但没有更新出现的上下文菜单。
在此基础上我怀疑这是一个竞争条件:有时启动Chrome渲染上下文菜单之前的代码完全跑了。
我尝试添加一个事件监听到“文本菜单”和“鼠标松开”。 当用户选择与鼠标的文字,因此它改变多之前它出现(甚至几秒钟)的文本菜单的后面的触发器。 即使有这样的技术,我仍然看到了同样的错误发生!
这种情况往往在Chrome 22.0.1229.94(苹果机),偶见于铬20.0.1132.47(Linux版),并没有在2分钟内试图在Windows器(Chrome 22.0.1229.94)发生。
这是怎么回事到底是什么? 我该如何解决呢? 还有没有其他的解决方法吗?
这里是我的代码的简化版本(并非如此简单,因为我保持的日志消息):
manifest.json的:
{
"name": "Test",
"version": "0.1",
"permissions": ["contextMenus"],
"content_scripts": [{
"matches": ["http://*/*", "https://*/*"],
"js": ["content_script.js"]
}],
"background": {
"scripts": ["background.js"]
},
"manifest_version": 2
}
content_script.js
function loadContextMenu() {
var selection = window.getSelection().toString().trim();
chrome.extension.sendMessage({request: 'loadContextMenu', selection: selection}, function (response) {
console.log('sendMessage callback');
});
}
document.addEventListener('mousedown', function(event){
if (event.button == 2) {
loadContextMenu();
}
}, true);
background.js
function SelectionType(str) {
if (str.match("^[0-9]+$"))
return "number";
else if (str.match("^[a-z]+$"))
return "lowercase string";
else
return "other";
}
chrome.extension.onMessage.addListener(function(msg, sender, sendResponse) {
console.log("msg.request = " + msg.request);
if (msg.request == "loadContextMenu") {
var type = SelectionType(msg.selection);
console.log("selection = " + msg.selection + ", type = " + type);
if (type == "number" || type == "lowercase string") {
console.log("Creating context menu with title = " + type);
chrome.contextMenus.removeAll(function() {
console.log("contextMenus.removeAll callback");
chrome.contextMenus.create(
{"title": type,
"contexts": ["selection"],
"onclick": function(info, tab) {alert(1);}},
function() {
console.log("ContextMenu.create callback! Error? " + chrome.extension.lastError);});
});
} else {
console.log("Removing context menu")
chrome.contextMenus.removeAll(function() {
console.log("contextMenus.removeAll callback");
});
}
console.log("handling message 'loadContextMenu' done.");
}
sendResponse({});
});