完全失去了如何保存扩展弹出窗口的内容 [英] Completely lost on how to save extension popup window content

查看:167
本文介绍了完全失去了如何保存扩展弹出窗口的内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我几乎不知道如何让每次打开新链接或点击离开时,弹出窗口的添加内容不会消失。我已经阅读过关于内容脚本,背景脚本等的内容,但我并不真诚地知道如何将其实现到我自己的源代码中。以下是我的 popup.html popup.js 和我的 manifest.js 文件。

{
manifest_version:2,
name:URL_save,
description:

version:0.1,

browser_action:{
这个扩展名保存了一个URL并将标题重命名为用户的意愿并超链接了标题。 default_icon:/img/icon.png,
default_popup:popup.html,
default_title:查看您保存的网站!
},

权限:[
标签

}

弹出式HTML

 < HTML> 
< head>
< title>您的文章< / title>
< link href =/ css / style.css =stylesheet/>
< script src =/ js / underscore-min.js>< / script>
< script src =/ js / popup.js>< / script>
< / head>
< body>
< div id =div>暂无内容!点击按钮添加当前网站的链接!< / div>
< div>< ul id =list>< / ul>< / div>
< br />
< button id =button>添加链接!< / button>
< / body>
< / html>

popup.js

  //全局变量
var url;

//弹出窗口中按钮的事件监听器
document.addEventListener('DOMContentLoaded',function(){
var button = document.getElementById('button');
button.addEventListener('click',function(){
addLink();
});
});

//获取当前选项卡的URL,在窗口内添加
函数addLink(){
//将信息存储在queryInfo对象中:
// https://developer.chrome.com/extensions/tabs#method-query
var queryInfo = {
currentWindow:true,
active:true
};

chrome.tabs.query(queryInfo,function(tabs){
// tabs是一个数组,因此可以获取标签
中的第一个(也是唯一的)对象元素//将URL的标签页放在另一个变量中:
// https://developer.chrome.com/extensions/tabs#type-Tab $ b $ url url = tabs [0] .url;

//格式html
var html ='< li>< a href ='+ url +target ='_ blank'>+ url +'< / a>< b / b>< / li>';

//更改短信
document.getElementById(div)。innerHTML =< h2>保存的页面< / h2> ;;

//获取到无序列表并为新列表项创建空间
var list = document.getElementById(list);
var newcontent = document.createElement ('LI');
newcontent.innerHTML = html;

// while循环记住以前的内容并追加新的内容
while(newcontent.firstChild){
list.appendChild(newcontent.firstChild);
}
});





$ b

在这张图片中,你会看到当我第一次添加一个链接但接着关闭时会发生什么(仅)弹出窗口,再次打开它:



添加当前网址后:

p>

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

解决方案

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



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



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



<使用 chrome.storage StorageArea MDN 是数据可直接用于扩展的所有部分,而不需要将数据作为消息传递。



您当前的代码



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



Google在选项文档页面 2, MDN 显示存储 chrome.storage.sync 并将值恢复到DOM显示选项页面。本例中使用的代码可以使选项页面完全按照弹出窗口的原样工作,只需将它的HTML页面定义为 default_popup 即可为 browser_action 。还有很多其他的例子。



不幸的是,没有更多关于你想要的细节,很难给你特定的代码。但是,有几条建议可以指导你走向哪个方向:


  • 重构你的代码,这样你就可以调用一个单独的函数将URL作为参数添加到您在DOM中的列表(例如 addUrlToDom(url))。当用户添加一个URL并且当页面加载时URL被恢复时,这个函数将被使用。

  • 将你的URL列表存储在一个数组中(例如 urlList )。这个数组将被保存到弹出窗口之外的存储位置。您将从 DOMContentLoaded 处理程序中的存储位置读取该数组,并使用重构的 addUrlToDom()函数来添加每个值。将它恢复到DOM中可能类似于:

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




将数据存储在 chrome.storage.local



假设您想要在Chrome本地计算机上存储URL关机/重新启动(例如使用 chrome.storage.local ),您的代码可能如下所示:
$ b manifest.json 更改至权限只:
$ b $

 权限:[
tab,
storage
]

popup.js


$ b

  //全局变量
var urlList = [];

document.addEventListener('DOMContentLoaded',function(){
getUrlListAndRestoreInDom();
//弹出窗口中按钮的事件侦听器
document.getElementById 'button')。addEventListener('click',addLink);
});

//获取当前标签的URL,在窗口中添加
函数addLink(){
chrome.tabs.query({currentWindow:true,active:true} ,函数(标签){
// tabs是一个数组,因此可以获取标签
var url = tabs [0] .url;
中的第一个(也是唯一的)对象元素if(urlList .indexOf(url)=== -1){
//不要添加重复
addUrlToListAndSave(url);
addUrlToDom(url);
}
});
}
$ b $ function getUrlListAndRestoreInDom(){
chrome.storage.local.get({urlList:[]},function(data){
urlList = data。 urlList;
urlList.forEach(function(url){
addUrlToDom(url);
});
});
}

函数addUrlToDom(url){
//改变文字信息
document.getElementById(div)。innerHTML =< h2> Saved页面< / H2>中;

//在这里插入HTML文本是个不错的主意,因为当
//包括内容不完全来自您的扩展(例如url)时,它可能存在安全漏洞。
//如果从
//扩展名中纯粹插入HTML文本,那么就可以了。
/ *
//格式HTML
var html ='< li>< a href ='+ url +target ='_ blank'> + url +'< / a>< / li>';
//将URL添加到DOM
document.getElementById(list)。insertAdjacentHTML('beforeend',html);
* /
//以编程方式构建新的DOM元素:
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);
}

函数addUrlToListAndSave(url){
if(urlList.indexOf(url)=== -1){
// URL尚不在列表中
urlList.push(url);
saveUrlList();



function saveUrlList(callback){
chrome.storage.local.set({urlList},function(){
if( typeof callback ==='function'){
//如果没有提供回调,不要尝试调用它。
callback();
}
}) ;

$ / code>







  1. 这个例外是你插入到页面上下文中的脚本。页面上下文是你可能不会运行脚本的东西。为此,你必须使用内容脚本(你的 StorageArea MDN 数据可直接使用)将< script> 标记插入到网页的DOM中。这可能有点复杂,你可能不需要关心它。这里提到的仅仅是因为对于 StorageArea 声明可能存在例外情况, MDN 数据可用于您的扩展程序的所有区域。

  2. Chrome文档中的示例在Firefox上运行良好。是, Firefox支持 chrome。* ,使用回调和浏览器。* ,使用promise


I'm pretty much lost on how to make the added contents of my popup window not disappear every time I open a new link or click it "away". I've read about content script, background script and the like but I don't honestly know how to implement that into my own source code. Below is my popup.html, popup.js and my manifest.js file.

{
    "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);
        }
    });
}

In this images you see what happens when I first add a link but then close (only) the popup window, opening it again:

After adding the current URL:

After closing and re-opening the popup:

解决方案

Similar to a web page, the popup's (or an options/settings page's) scope is created when it is shown and destroyed when it is no longer visible. This means that there is no state stored within the popup itself between the times that it is shown. Any information which you desire to persist after the popup is destroyed, you will need to store somewhere else. Thus, you will need to use JavaScript to store any state which you desire to have be the same the next time the popup is opened. Each time the popup is opened, you will need to retrieve that information and restore it to the DOM. The two most commonly used places are a StorageAreaMDN, or the background page.

Where you store the information will depend on how long you want the data you store to persist, and where you want the data to be seen.

The general locations where you could store data include (other possibilities exist, but the followin are the most common):

  • The background page if you want the data to exist only until Chrome is closed. It will not exist once Chrome is restarted. You can send the data to the background page through a couple/few different methods, including message passingMDN, or directly changing values on the background pageMDN. Data stored in the StorageArea (the two options below) is also available to the background page, and content scripts.
  • chrome.storage.localMDN if you want the data to persist on the local machine across Chrome being closed and restarted.
  • chrome.storage.syncMDN if you want the data shared with all instances of Chrome which use the current Chrome account/profile. The data will also persist until changed. It will be available through Chrome being closed and restarted. It will be available on other machines using the same profile.
  • window.localStorage: Prior to the existence of chrome.storage it was popular to store data for the extension in window.localStorage. While this will still work, it is generally preferred to use chrome.storage.

One of the advantages of using a chrome.storage StorageAreaMDN is that the data is directly available to all portions of your extension without the need to pass the data as a message.1

Your current code

Currently your code is not storing the URLs that are entered anywhere other than in the DOM of the popup. You will need to establish a data structure (e.g. an array) in which you store the list of URLs. This data can then be stored into one of the storage locations mentioned above.

Google's example on the Options documentation page2, MDN shows storing chrome.storage.sync and restoring values into the DOM when the options page is displayed. The code used in this example can for the options page can work exactly as-is for a popup by just defining its HTML page as the default_popup for a browser_action. There are many other examples available.

Unfortunately, without more specifics from you as to what you desire, it is difficult to give you specific code. However, couple of suggestions to head in the direction you need to go are:

  • Refactor your code so you have a separate function that you call with a URL as a parameter which just adds this URL to the list you have in the DOM (e.g. addUrlToDom(url)). This function will be used when the user adds a URL and when the URLs are restored when the page loads.
  • Store your list of URLs in an array (e.g. urlList). This array will be what you save into the storage location outside of your popup. You will read this array from that storage location in your DOMContentLoaded handler and use the refactored addUrlToDom() function to add each value. Restoring it into the DOM could look something like:

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

Storing your data in chrome.storage.local

Assuming you want to store the URLs on the local machine across Chrome shutdown/restart (i.e. use chrome.storage.local), you code could look something like:

manifest.json changes to permissions only:

    "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 (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();
        }
    });
}


  1. The exception to this is scripts which you insert into the page context. The page context is something you will probably not be running scripts in. To do so you have to use a content script (where your StorageAreaMDN data is directly available) to insert a <script> tag into the DOM of a web page. This can be a bit complex, any you probably don't need to be concerned about it. It is mentioned here merely because there is a possible exception to the statement that the StorageAreaMDN data is available to all areas of your extension.
  2. The example in the Chrome documenation works just fine on Firefox. Yes, Firefox supports both chrome.*, using callbacks, and browser.*, using promises.

这篇关于完全失去了如何保存扩展弹出窗口的内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆