Разширение за Chrome запазва стойности от Background.js в хранилище и се показва на popup.html

В момента пиша просто разширение за 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='/bgstyle.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"
  }
}

person cleme001    schedule 19.11.2018    source източник


Отговори (1)


  1. Не използвайте popup.js като скрипт за съдържание. Нямате нужда от скрипт за съдържание. Вижте общия преглед на архитектурата. Скриптовете за съдържание имат ограничен достъп до API на chrome и се изпълняват в уеб страницата, а не в изскачащия прозорец за действие на браузъра, който е напълно отделна страница с пълно разширение със собствен chrome-extension:// URL адрес и собствена конзола за инструменти за разработка и т.н., които не са свързани с уеб страницата.
  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 е асинхронен, така че обратното извикване се извиква на по-късен етап, това е като еднократен слушател на събития „onload“. Има много уроци за асинхронен 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 polyfill (използвайки маркер <script> във вашия popup.html точно преди изскачащия прозорец .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});
})();
person wOxxOm    schedule 19.11.2018