如何在Greasemonkey中将变量传递给事件侦听器?

时间:2018-01-28 12:25:01

标签: javascript greasemonkey

我为Firefox编写了一个Greasemonkey脚本,它为当前.NET文档网页上的每个方法添加了返回类型和参数名称。例如,在描述SortedSet<T>Add(T)的网页上,将更改为bool Add(T item)签名,依此类推。该脚本可以正确下载所有方法的签名 - 请参阅console.log(s)。我还可以通过取消注释node.textContent = "*changed*"来更改每行中“名称”列的内容。不幸的是,如果我想将Name列的内容设置为适当的签名,则这仅适用于第一行。看起来节点变量没有正确地传递给for循环中的事件监听器。

以下是完整的脚本代码:

// ==UserScript==
// @name     Unnamed Script 785375
// @include  https://msdn.microsoft.com/en-us/*
// @version  1
// @grant    none
// ==/UserScript==

//get all links in Name column of Constructors, Properties and Methods tables
var nodes = document.evaluate("//table[@id='idConstructors' or @id='idProperties' or @id='idMethods']/tbody/tr/td[@data-th='Name']/a",
                              document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);

//update text of each link to contain the full signature of the class member
for (var i = nodes.snapshotLength - 1; i >= 0; i--) {
  var node = nodes.snapshotItem(i);
  //node.textContent = "*changed*";

  //the signature is found in the first pre tag on the webpage pointed by the current link
  var oReq = new XMLHttpRequest();
  oReq.addEventListener("load", function() {
    var html = document.createElement('html');
    html.innerHTML = this.responseText;
    var elements = html.getElementsByTagName('pre');
    var s = elements[0].textContent;
    s = s.replace(/\n/g, "");   //remove unnecessary white space from the signature
    s = s.replace(/\t/g, " ");
    s = s.replace(/\( /g, "(");
    console.log(s);
    node.textContent = s;
  });
  oReq.open("GET", node.getAttribute("href"));
  oReq.send();
}

和当前不正确的结果:

enter image description here

1 个答案:

答案 0 :(得分:-1)

这是循环中JavaScript闭包的常见问题。 改变:

var node = nodes.snapshotItem(i);

为:

const node = nodes.snapshotItem(i);

会有所帮助。