完全失去了如何保存扩展popup窗口的内容

我几乎失去了如何使我的popup窗口的添加内容不会消失,每次我打开一个新的链接或点击它“离开”。 我已经阅读了关于内容脚本,后台脚本之类的东西,但是我不老实地知道如何将其实现到我自己的源代码中。 以下是我的popup.htmlpopup.js和我的manifest.js文件。

{ "manifest_version": 2, "name": "URL_save", "description": "This extension saves an URL and renames the title to the user's wishes and hyperlink the title.", "version": "0.1", "browser_action": { "default_icon": "/img/icon.png", "default_popup": "popup.html", "default_title": "See your saved websites!" }, "permissions": [ "tabs" ] } 

popup的HTML

 <html> <head> <title>Your articles</title> <link href="/css/style.css" rel="stylesheet"/> <script src="/js/underscore-min.js"></script> <script src="/js/popup.js"></script> </head> <body> <div id="div">No content yet! Click the button to add the link of the current website!</div> <div><ul id="list"></ul></div> <br/> <button id="button">Add link!</button> </body> </html> 

popup.js

 // global variables var url; // event listener for the button inside popup window document.addEventListener('DOMContentLoaded', function() { var button = document.getElementById('button'); button.addEventListener('click', function() { addLink(); }); }); // fetch the URL of the current tab, add inside the window function addLink() { // store info in the the queryInfo object as per: // https://developer.chrome.com/extensions/tabs#method-query var queryInfo = { currentWindow: true, active: true }; chrome.tabs.query(queryInfo, function(tabs) { // tabs is an array so fetch the first (and only) object-elemnt in tab // put URL propery of tab in another variable as per: // https://developer.chrome.com/extensions/tabs#type-Tab url = tabs[0].url; // format html var html = '<li><a href=' + url + " target='_blank'>" + url + '</a><br/></li>'; // change the text message document.getElementById("div").innerHTML = "<h2>Saved pages</h2>"; // get to unordered list and create space for new list item var list = document.getElementById("list"); var newcontent = document.createElement('LI'); newcontent.innerHTML = html; // while loop to remember previous content and append the new ones while (newcontent.firstChild) { list.appendChild(newcontent.firstChild); } }); } 

在这个图像中,你可以看到当我第一次添加一个链接时会发生什么,然后closures(仅)popup窗口,再次打开它:

添加当前url后:
之前

closures并重新打开popup窗口后:
后

与网页类似,popup窗口(或选项/设置页面)的作用域在其不可见时显示并被销毁时创build。 这意味着在popup窗口中显示的时间之间没有任何状态存储。 在popup窗口被破坏之后,您希望保留的任何信息都需要存储在其他地方。 因此,您将需要使用JavaScript来存储您希望在下次打开popup窗口时所需的任何状态。 每次打开popup窗口时,您都需要检索该信息并将其恢复到DOM。 两个最常用的地方是StorageArea MDN或后台页面。

您存储信息的位置取决于您要存储的数据持续多久,以及您希望看到数据的位置。

您可以存储数据的一般位置包括(其他可能性存在,但以下是最常见的):

  • 如果您希望数据仅在Chromeclosures之前存在,则为后台页面。 一旦Chrome重新启动,它将不会存在。 您可以通过一些/几种不同的方法将数据发送到后台页面,包括消息传递 MDN ,或直接更改背景页面 MDN 上的值 。 存储在StorageArea中的数据(以下两个选项)也可用于后台页面和内容脚本。
  • chrome.storage.local MDN,如果你希望数据在本地计算机上保持closures并重新启动。
  • chrome.storage.sync MDN,如果您希望数据与所有使用当前Chrome帐户/configuration文件的Chrome实例共享。 数据也会一直存在,直到更改。 Chrome会closures并重新启动。 它将在其他机器上使用相同的configuration文件。
  • window.localStorage :在存在chrome.storage之前,在window.localStorage存储扩展数据非常受欢迎。 虽然这仍然有效,但通常最好使用chrome.storage

使用chrome.storage StorageArea MDN的好处之一是数据可直接用于扩展的所有部分,而无需将数据作为消息传递。 1

您当前的代码

目前您的代码不会存储在popup窗口的DOM以外的地方input的URL。 您将需要build立一个数据结构(例如一个数组),在其中存储URL列表。 这个数据然后可以被存储到上面提到的存储位置之一中。

在Options文档页面 2上的Google示例中, MDN显示了存储chrome.storage.sync并在显示选项页面时将值恢复到DOM中。 在这个例子中使用的代码可以通过将其HTML页面定义为browser_actiondefault_popup来使选项页面完全按照popup窗口的browser_action 。 还有很多其他的例子可用。

不幸的是,没有更多关于你想要的细节,很难给你特定的代码。 然而,你需要去的方向有几个build议是:

  • 重构你的代码,所以你有一个单独的函数,你调用一个URL作为参数, 只是将这个URL添加到你在DOM中的列表(例如addUrlToDom(url) )。 当用户添加一个URL时,这个函数将被使用,当页面加载的时候URL被恢复。
  • 将你的URL列表存储在一个数组中(例如urlList )。 这个数组将被保存到popup窗口以外的存储位置。 您将从DOMContentLoaded处理程序的存储位置读取该数组,并使用重构的addUrlToDom()函数来添加每个值。 将其恢复到DOM可能看起来像这样:

     urlList.forEach(function(url){ addUrlToDom(url); }); 

将数据存储在chrome.storage.local

假设你想通过Chrome关机/重新启动(例如使用chrome.storage.local )在本地机器上存储URL,你的代码可能看起来像这样:

manifest.json仅更改permissions

  "permissions": [ "tabs", "storage" ] 

popup.js

 // global variables var urlList=[]; document.addEventListener('DOMContentLoaded', function() { getUrlListAndRestoreInDom(); // event listener for the button inside popup window document.getElementById('button').addEventListener('click', addLink); }); // fetch the URL of the current tab, add inside the window function addLink() { chrome.tabs.query({currentWindow: true,active: true}, function(tabs) { // tabs is an array so fetch the first (and only) object-element in tab var url = tabs[0].url; if(urlList.indexOf(url) === -1){ //Don't add duplicates addUrlToListAndSave(url); addUrlToDom(url); } }); } function getUrlListAndRestoreInDom(){ chrome.storage.local.get({urlList:[]},function(data){ urlList = data.urlList; urlList.forEach(function(url){ addUrlToDom(url); }); }); } function addUrlToDom(url){ // change the text message document.getElementById("div").innerHTML = "<h2>Saved pages</h2>"; //Inserting HTML text here is a bad idea, as it has potential security holes when // including content not sourced entirely from within your extension (eg url). // Inserting HTML text is fine if it is _entirely_ sourced from within your // extension. /* // format HTML var html = '<li><a href=' + url + " target='_blank'>" + url + '</a></li>'; //Add URL to DOM document.getElementById("list").insertAdjacentHTML('beforeend',html); */ //Build the new DOM elements programatically instead: var newLine = document.createElement('li'); var newLink = document.createElement('a'); newLink.textContent = url; newLink.setAttribute('href',url); newLink.setAttribute('target','_blank'); newLine.appendChild(newLink); document.getElementById("list").appendChild(newLine); } function addUrlToListAndSave(url){ if(urlList.indexOf(url) === -1){ //URL is not already in list urlList.push(url); saveUrlList(); } } function saveUrlList(callback){ chrome.storage.local.set({urlList},function(){ if(typeof callback === 'function'){ //If there was no callback provided, don't try to call it. callback(); } }); } 

  1. 这个例外是你插入页面上下文的脚本。 页面上下文是你可能不会运行脚本的东西。要做到这一点,你必须使用一个内容脚本(你的StorageArea MDN数据是直接可用的)插入一个<script>标签到网页的DOM中。 这可能有点复杂,你可能不需要关心它。 这里提到的仅仅是因为StorageArea MDN数据可用于扩展的所有区域的声明可能有一个例外。
  2. Chrome文档中的示例在Firefox上运行得很好。 是的, Firefox支持chrome.* ,使用callback和browser.* ,使用promises 。

每次closures/重新打开时,popup窗口都会重新载入文档。 相反,你应该使用后台页面来保存状态。

一般的做法是:

  1. 从popup窗口到背景进行通信来做些事情。 即︰做一个Ajax请求,并将结果存储在一个普通的JavaScript对象。
  2. 从后台页面获取javascript对象。 即使您closurespopup窗口,状态仍保留在后台页面中。