【问题标题】:Remember array after the popup has closed in a Chrome extension在 Chrome 扩展程序中关闭弹出窗口后记住数组
【发布时间】:2017-08-04 16:37:49
【问题描述】:

我有一些编程知识,但是我之前没有广泛使用 Javascript 或处理过 Chrome 扩展程序。我正在寻找一个 Chrome 扩展程序,可以在新选项卡中打开选定的链接(这是我想要实现的初始目标,因为我的最终目标是在同一选项卡的框架中打开链接 - 如果可能的话 - 在为了从这些链接中保存图像,类似于 Firefox 的 Save Images 扩展程序正在执行的操作)。

我有一个问题:弹出窗口中的选定链接没有被“记住”,以便在弹出窗口关闭后延迟打开它们(由于打开新选项卡)。我猜这与不制作后台脚本来执行操作有关,而不是popup.js?也许这两个Javascipt文件之间传递了一些消息?只是在这里猜测......

到目前为止,这是我的代码:

ma​​nifest.json

{
  "name": "Get links",
  "version": "1.0",
  "manifest_version": 2,
  "description": "Get links from a page",
  "browser_action": {
    "default_icon": "icon.png",
    "default_popup": "popup.html"
  },
  "permissions": ["tabs", "downloads", "<all_urls>"]
}

popup.html

<!DOCTYPE html>
<html>
  <head>
    <script src="popup.js"></script>
  </head>
  <body style="width:400px;">
    <form id="linksform">
      <p>
        <label for="matchregex" style="margin-left: 7px;">RegEx Match: </label>
        <input id="regextext" type="text" style="width:90px;" name="matchregex" value="" />
        <input id="togglematches" type="button" value="Toggle Matches" />
        <input id="openselected" type="button" value="Open Selected" />
      </p>
      <table id='links'>
        <th></th>
      </table>
    </form>
  </body>
</html>

popup.js

var alllinks = [];
var visiblelinks = [];
var selectedlinks = [];
var delay = 1000;

// Display all visible links.

function showlinks()
  {
  var togglematchesbutton = document.getElementById('togglematches');
  var openselectedbutton = document.getElementById('openselected');
  var linkstable = document.getElementById('links');
  while (linkstable.children.length > 1)
    {
    linkstable.removeChild(linkstable.children[linkstable.children.length - 1])
    }
  for (var i = 0; i < visiblelinks.length; ++i)
    {
    var row = document.createElement('tr');
    var col0 = document.createElement('td');
    var col1 = document.createElement('td');
    var checkbox = document.createElement('input');
    checkbox.type = 'checkbox';
    checkbox.id = 'check' + i;
    checkbox.checked = false;
    checkbox.value = visiblelinks[i];
    col0.appendChild(checkbox);
    col1.innerText = visiblelinks[i];
    col1.style.whiteSpace = 'nowrap';
    col1.onclick = function()
      {
      checkbox.checked = !checkbox.checked;
      }
    row.appendChild(col0);
    row.appendChild(col1);
    linkstable.appendChild(row);
    }
  togglematchesbutton.onclick = function()
    {
    var regex = new RegExp(document.getElementById("regextext").value);
    var getinputs = document.getElementsByTagName("input");
    for (var i = 0, max = getinputs.length; i < max; i++)
      {
      if ((getinputs[i].type === 'checkbox') &&  (regex.test(getinputs[i].value))) getinputs[i].checked = !getinputs[i].checked;
      }
    }
  openselectedbutton.onclick = function()
    {
    var getinputs = document.getElementsByTagName("input");
    for (var i = 0, max = getinputs.length; i < max; i++)
      {
      if ((getinputs[i].type === 'checkbox') && (getinputs[i].checked))
        {
        selectedlinks.push(getinputs[i].value);
        }
      }
    for (var i = 0, max = selectedlinks.length; i < max; i++)
      {
      window.setTimeout(function() {chrome.tabs.create({url: selectedlinks[i]});}, delay);
      //chrome.tabs.create({url: selectedlinks[i]});
      }
    }
  }

// Add links to alllinks and visiblelinks, sort and show them. Sendlinks.js is
// injected into all frames of the active tab, so this listener may be called
// multiple times.

chrome.extension.onMessage.addListener
  (
  function(links)
    {
    for (var index in links)
      {
      alllinks.push(links[index]);
      }
    alllinks.sort();
    visiblelinks = alllinks;
    //console.log(links);
    showlinks();
    }
  );

// Set up event handlers and inject sendlinks.js into all frames in the active
// tab.

window.onload = function()
  {
  chrome.windows.getCurrent
    (
    function (currentWindow)
      {
      chrome.tabs.query
        (
        {active: true, windowId: currentWindow.id},
        function(activeTabs)
          {
          chrome.tabs.executeScript(activeTabs[0].id, {file: 'sendlinks.js', allFrames: true});
          }
        );
      }
    );
  };

sendlinks.js

// Send back to the popup a sorted deduped list of valid link URLs on this page.
// The popup injects this script into all frames in the active tab.
console.log("Injected");

var links = [].slice.apply(document.getElementsByTagName('a'));
console.log(links);
links = links.map
  (
    function(element)
    {
    // Return an anchor's href attribute, stripping any URL fragment (hash '#').
    // If the html specifies a relative path, chrome converts it to an absolute
    // URL.
    var href = element.href;
    var hashIndex = href.indexOf('#');
    if (hashIndex >= 0)
      {
      href = href.substr(0, hashIndex);
      }
    return href;
    }
  );

links.sort();

// Remove duplicates and invalid URLs.
var kBadPrefix = 'javascript';
for (var i = 0; i < links.length;)
  {
  if (((i > 0) && (links[i] == links[i - 1])) || (links[i] == '') || (kBadPrefix == links[i].toLowerCase().substr(0, kBadPrefix.length)))
    {
    links.splice(i, 1);
    }
  else
    {
    ++i;
    }
  }
console.log(links);

chrome.extension.sendMessage(links);

注意:这段代码的大部分内容取自其他地方,并已根据我的需要进行了修改。

主要问题在于 popup.js 中的这段代码 sn-p:

for (var i = 0, max = selectedlinks.length; i < max; i++)
  {
  window.setTimeout(function() {chrome.tabs.create({url: selectedlinks[i]});}, delay);
  //chrome.tabs.create({url: selectedlinks[i]});
  }

如果我注释 setTimeout 行并取消注释以下行,它可以工作(例如,扩展程序成功打开选项卡),但它不使用打开连续选项卡之间的延迟 - 这是避免“请求过多”所必需的某些网站上的错误。如果我让它保持原样,它会打开它应该打开的选项卡数量(使用指定的延迟),但这些选项卡的 url 与所选值不匹配(基本上,它们是空白的)。我想要的是后者发生,但打开选定的链接而不是空白标签。

您能否指出我的错误在哪里,并建议修改代码以使其正常工作?如果可行,通过使现有代码尽可能接近发布的版本(也就是只对源代码进行少量修改)。谢谢。

【问题讨论】:

    标签: javascript arrays google-chrome background popup


    【解决方案1】:

    没关系,我解决了这个问题。事实证明,由于某种原因,Chrome 不记得 for 循环内的 i 变量(可能是因为 settimeout() 与 @ 相比异步工作987654323@循环,由于延迟?),所以它无法引用正确的数组元素。

    我所要做的就是替换上面的

    window.setTimeout(function() {chrome.tabs.create({url: selectedlinks[i]});}, delay);
    

    window.setTimeout(function() {chrome.tabs.create({url: selectedlinks.shift()});}, delay);
    

    它完美地工作。基本上,更新的代码不是使用 i 变量引用数组元素,而是始终引用第一个数组元素,同时将其删除,从而“导航”遍历整个数组并消除已为其创建选项卡的元素。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-07
      • 2011-04-26
      • 1970-01-01
      • 1970-01-01
      • 2023-01-02
      • 2015-06-09
      • 2018-07-22
      相关资源
      最近更新 更多