Ответ 1
API contextMenus
используется для определения записей в контекстном меню. Его не нужно вызывать прямо перед открытием контекстного меню. Таким образом, вместо создания записей в событии contextmenu используйте событие selectionchange
, чтобы постоянно обновлять запись contextmenu.
Я покажу простой пример, который просто отображает выделенный текст в записи контекстного меню, чтобы показать, что записи синхронизированы хорошо.
Используйте этот контент script:
document.addEventListener('selectionchange', function() {
var selection = window.getSelection().toString().trim();
chrome.runtime.sendMessage({
request: 'updateContextMenu',
selection: selection
});
});
На заднем плане мы собираемся создать запись contextmenu только один раз. После этого мы обновляем элемент contextmenu (используя идентификатор, который мы получаем из chrome.contextMenus.create
).
Когда выбор пуст, мы удаляем запись контекстного меню, если это необходимо.
// ID to manage the context menu entry
var cmid;
var cm_clickHandler = function(clickData, tab) {
alert('Selected ' + clickData.selectionText + ' in ' + tab.url);
};
chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
if (msg.request === 'updateContextMenu') {
var type = msg.selection;
if (type == '') {
// Remove the context menu entry
if (cmid != null) {
chrome.contextMenus.remove(cmid);
cmid = null; // Invalidate entry now to avoid race conditions
} // else: No contextmenu ID, so nothing to remove
} else { // Add/update context menu entry
var options = {
title: type,
contexts: ['selection'],
onclick: cm_clickHandler
};
if (cmid != null) {
chrome.contextMenus.update(cmid, options);
} else {
// Create new menu, and remember the ID
cmid = chrome.contextMenus.create(options);
}
}
}
});
Чтобы этот пример был прост, я предположил, что есть только одна запись в контекстном меню. Если вы хотите поддерживать больше записей, создайте массив или хеш для хранения идентификаторов.
Советы
- Оптимизация. Чтобы уменьшить количество вызовов API
chrome.contextMenus
, кешируйте соответствующие значения параметров. Затем используйте простое сравнение===
, чтобы проверить, нужно ли создавать/обновлять элемент contextMenu. - Отладка. Все методы
chrome.contextMenus
являются асинхронными. Чтобы отладить ваш код, передайте функцию обратного вызова.create
,.remove
или.update
.