Расширение Chrome Сохранение значений из Background.js в хранилище и отображение в popup.html - PullRequest
0 голосов
/ 19 ноября 2018

В настоящее время я пишу простое расширение Chrome, которое сохраняет текущую веб-страницу в локальном хранилище, когда вы щелкаете значок расширения в заголовке.

Я успешно сохранил URL в локальном хранилище, используя background.js в соответствии с документацией Chrome здесь: https://developer.chrome.com/extensions/activeTab.

Моя проблема заключается в том, что когда я в первый раз щелкаю по значку расширения Chrome, мое событие запускается, но мои ошибки popup.js выводятся с

Uncaught TypeError: Cannot read property 'getSelected' of undefined

background.js

chrome.browserAction.onClicked.addListener(function(tab) {

  console.log('Turning ' + tab.url + ' red!');
  var tabNew = tab.url
  chrome.storage.sync.set({ ["key" + 1]:  tabNew}, function(){
      //  A data saved callback omg so fancy
  });

  chrome.storage.sync.get(/* String or Array */["key" + 1], function(items){
      //  items = [ { "yourBody": "myBody" } ]
      console.log(items)
  });


  chrome.tabs.executeScript({
    code: 'document.body.style.backgroundColor="red"'
  });

  chrome.browserAction.setPopup({popup: 'popup.html'});


});

popup.js

chrome.tabs.getSelected(null, function(tab) {
    document.getElementById('currentLink').innerHTML = tab.url;
});



document.addEventListener('DOMContentLoaded', function() {
    var link = document.getElementById('download');
    // onClick's logic below:
    link.addEventListener('click', function() {
        chrome.storage.sync.get(null, function(items) { // null implies all items
            // Convert object to a string.
            var result = JSON.stringify(items);

            // Save as file
            chrome.downloads.download({
                url: 'data:application/json;base64,' + btoa(result),
                filename: 'filename_of_exported_file.json'
            });
        });        
    });
});

popup.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head> 

    <link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'> 
    <link href='style.css' rel='stylesheet' type='text/css'> 

    <title>Discoveroo</title> 

    <!-- <script type="text/javascript" src="https://www.google.com/jsapi"></script>  -->
    <base target="_blank">

</head>

<body>
<p id="currentLink">Loading ...</p>
<hr />
<ul id="savedLinks"></ul>
<script type="text/javascript" src="popup.js"></script>

<button id="download">Download All</button>
</body>
</html>

manifest.json

{
  "name": "APPNAME",
  "version": "0.1",
  "manifest_version": 2,
  "description": "APP DESC",
  "permissions": ["activeTab", "storage", "downloads", "<all_urls>"], 
  "background": {
    "scripts": ["background.js"],
    "persistent": true
  },
  "content_scripts": [{
    "matches": ["http://*/*", "https://*/*"],
    "js": ["popup.js"]
  }],
  "browser_action": {
    "default_title": "Add this page to my list"
  },
  "icons": {
    "128": "icon.png"
  }
}

1 Ответ

0 голосов
/ 19 ноября 2018
  1. Не используйте popup.js в качестве скрипта содержимого. Вам не нужен контент-скрипт. См. обзор архитектуры . Сценарии содержимого имеют ограниченный доступ к API Chrome и запускаются на веб-странице , а не во всплывающем окне browserAction, которое является полностью отдельной страницей полного расширения со своим собственным расширением chrome: // URL и own devtools console и т. д., не связанные с веб-страницей.
  2. browserAction.onClicked не работает одновременно с всплывающим HTML, поэтому вы должны выбрать один. В этом случае, поскольку вам нужно отобразить всплывающую страницу, объявите ее в manifest.json, удалите browserAction.onClicked, поместите ее внутренний код в ваш popup.js
  3. Как следствие, фоновый скрипт не понадобится
  4. Вероятно, вам не нужно разрешение <all_urls>, поскольку у вас уже есть activeTab, который дает вам полный доступ к активной вкладке после нажатия на значок расширения.
  5. chrome.tabs.getSelected устарела и будет удалена, поэтому используйте chrome.tabs.query({active: true, currentWindow: true}, tabs => { ... })
  6. Нет необходимости читать chrome.storage, поскольку вы уже получили активный URL в вашем popup.js.
  7. Что касается "omg so fancy", то обратные вызовы - это не произвольная странность, а следствие основного факта: API является асинхронным, поэтому обратный вызов вызывается в более поздний момент времени, это как разовая "загрузка" слушатель событий. Существует множество учебных пособий по асинхронному JavaScript.
  8. Используйте свойство safe textContent вместо потенциально небезопасного innerHTML для отображения простой текстовой строки, такой как URL.

manifest.json

  • удалить "background"
  • удалить "content_scripts"
  • добавить "default_popup"

    "browser_action": {
      "default_title": "Add this page to my list",
      "default_popup": "popup.html"
    },
    

background.js

Удалить.

popup.js

Единственные вещи из старого фонового скрипта, которые вам могут понадобиться, это вызовы executeScript и sync.set.

chrome.tabs.executeScript({
  code: 'document.body.style.backgroundColor="red"'
});

chrome.tabs.query({active: true, currentWindow: true}, ([tab]) => {
  document.getElementById('currentLink').textContent = tab.url;
  chrome.storage.sync.set({key1: tab.url});
});

Вы также можете загрузить полифилл Mozilla WebExtension (используя тег <script> в вашем popup.html прямо перед popup.js) и переключиться на синтаксис async / await вместо обратных вызовов:

(async () => {
  const [tab] = await browser.tabs.query({active: true, currentWindow: true});
  document.getElementById('currentLink').textContent = tab.url;
  await chrome.storage.sync.set({key1: tab.url});
})();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...