完全失去了如何保存扩展弹出窗口内容

Kob*_*ior 3 html javascript google-chrome google-chrome-extension firefox-addon-webextensions

每次打开新链接或"远离"点击它时,我都会失去如何使弹出窗口的添加内容不会消失.我已经阅读了有关内容脚本,后台脚本等的内容,但我并不知道如何将其实现到我自己的源代码中.下面是我的popup.html,popup.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"
    ]
}
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

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);
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

在此图像中,您将看到当我第一次添加链接但随后关闭(仅)弹出窗口时会发生什么,再次打开它:

添加当前网址后:
之前

关闭并重新打开弹出窗口后:
后

Mak*_*yen 12

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

存储信息的位置取决于您希望存储的数据持续多长时间以及您希望数据显示的位置.

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

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

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

您当前的代码

目前,您的代码不存储在弹出窗口的DOM以外的任何位置输入的URL.您需要建立一个数据结构(例如数组),您可以在其中存储URL列表.然后可以将该数据存储到上述存储位置之一中.

Google在选项文档第2上的示例,MDN显示chrome.storage.sync了在显示选项页面时将值存储和恢复到DOM中.在这个例子中使用可选项页面可以工作的代码完全一样,是由刚刚确定其HTML页面作为一个弹出式default_popupbrowser_action.还有许多其他例子可供使用.

不幸的是,如果没有您想要的更多细节,很难为您提供具体的代码.但是,有一些建议可以指向您需要的方向:

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

    urlList.forEach(function(url){
        addUrlToDom(url);
    });
    
    Run Code Online (Sandbox Code Playgroud)

存储您的数据 chrome.storage.local

假设您希望在Chrome关闭/重启(即使用chrome.storage.local)中将URL存储在本地计算机上,您的代码可能如下所示:

manifest.jsonpermissions仅更改为:

    "permissions": [
        "tabs",
        "storage"
    ]
Run Code Online (Sandbox Code Playgroud)

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 (e.g. 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();
        }
    });
}
Run Code Online (Sandbox Code Playgroud)
  1. 例外情况是您插入页面上下文的脚本.页面上下文可能不会运行脚本.为此,您必须使用内容脚本(您的StorageArea MDN数据可直接使用)将<script>标记插入到网页的DOM中.这可能有点复杂,任何你可能不需要担心它.这里提到的仅仅是因为存在一个可能的例外情况,即StorageArea MDN数据可用于扩展的所有区域.
  2. Chrome文档中的示例在Firefox上运行得很好.是的,Firefox支持chrome.*使用回调和browser.*使用promises.