Расширение Chrome: правильное добавление записи контекстного меню с непостоянной фоновой страницей

Я работаю над простым расширением для обмена ссылками (пинборд, удобочитаемость, вкуснота и т. д.), и у меня есть вопрос о том, как правильно работать с пунктом контекстного меню. На моей непостоянной фоновой странице я вызываю chrome.contextMenus.create и chrome.contextMenus.onClicked.addListener для настройки/ответа на контекстное меню.

Пункт контекстного меню работает как положено. Но на фоновой странице отображается следующая ошибка (сразу после ее запуска и до того, как я использовал запись):

contextMenus.create: Cannot create item with duplicate id id_share_link at chrome-extension://.../share.js:52:30 lastError:29 set  

Это заставило меня понять, что я ни в коем случае не удаляю элемент или слушателя. Мало зная о javascript и расширениях, мне остается только гадать, правильно ли я все делаю. Я предполагаю, что этот код верхнего уровня будет выполняться повторно каждый раз, когда вызывается фоновая страница. Таким образом, будут избыточные вызовы create и addListener (и, следовательно, ошибка, которую я вижу в журнале).

Я явно не могу выполнить очистку в ответ на приостановку, так как эти вызовы должны присутствовать, чтобы разбудить фоновый скрипт.

Должен ли я вести себя по-другому?


person Victor    schedule 22.08.2013    source источник


Ответы (3)


Вы можете справиться с этим одним из двух способов:

  1. Вы можете добавить контекстное меню и слушателей при установке, используя:

    chrome.runtime.onInstalled.addListener(function() {
      /* Add context menu and listener */
    });
    
  2. Вы можете удалить контекстное меню и прослушиватель, а затем повторно добавлять их каждый раз при вызове файла.

person zachallia    schedule 23.08.2013

Если вы хотите использовать страницу событий, то есть непостоянную фоновую страницу, как вы ее называете, вы должны зарегистрировать контекстное меню через contextMenus.create в обработчике событий runtime.onInstalled. , так как эти регистрации контекстного меню в любом случае «сохраняются».

Вы должны добавлять функцию прослушивания для события contextMenus.onClicked каждый раз, когда страница события перезагружается, поскольку регистрация вашего желания прослушивать это событие сохраняется, а сам обратный вызов обработчика — нет. Так что обычно вызывайте contextMenus.onClicked.addListener не из runtime.onInstalled, а из кода верхнего уровня или другого кода, который гарантированно будет выполняться каждый раз при загрузке страницы событий.[1]

person x a    schedule 25.10.2013

[решение может быть уже не так, читайте комментарий]

runtime.onInstalled не срабатывает, если вы отключаете/включаете расширение.
Мое решение состоит в том, чтобы всегда добавлять пункты меню и проглатывать ошибки:

'use strict';

{

  let seqId = 0;

  const createMenuLinkEntry = (title, tab2url) => {

    const id = (++seqId).toString();

    chrome.contextMenus.create({
      id: id,
      title: title,
      contexts: ['browser_action'],
    }, () => {

      const err = chrome.runtime.lastError;
      if(err) {
        console.warn('Context menu error ignored:', err);
      }

    });

  };

  createMenuLinkEntry('Go to Google', (tab) => 'https://google.com');
  createMenuLinkEntry('Go to GitHub', (tab) => 'https://github.com');

} // namespace
person ilyaigpetrov    schedule 17.03.2017
comment
Я не думаю, что это точно (больше). У меня есть надстройка, которая создает контекстное меню в прослушивателе onInstalled. После отключения аддона его пункт контекстного меню удаляется, но повторное включение аддона возвращает его обратно. Таким образом, либо событие все равно срабатывает, либо отключение аддона не удаляет его контекстные меню, а только скрывает их. - person Marnes; 19.11.2017