I have some links in a page. I want to count the responses of each link and insert the numbers in front of the links. Here is what I have:
var links = document.evaluate('..../td[1]/font//a[@href]', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
var headings = document.evaluate('.../td[1]',document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null)
for(var i = 0; i < links.snapshotLength; i++){
var urls = links.snapshotItem(i).href;
GM_xmlhttpRequest({
method: 'GET',
url: urls,
onload function (res){
var dt = document.implementation.createDocumentType("html",
"-//W3C//DTD HTML 4.01 Transitional//EN", "http://www.w3.org/TR/html4/loose.dtd");
doc = document.implementation.createDocument('', '', dt);
html = doc.createElement('html');
html.innerHTML = res.responseText;
doc.appendChild(html);
var responses = doc.evaluate('.../tr', doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
var nResponse = responses.snapshotLength - 1;
var numResponse = document.createElement('font');
numResponse.innerHTML =
'<b>' + nResponse +
'</b>' ;
headings.snapshotItem(i).parentNode.insertBefore(numResponse, headings.snapshotItem(i));
}
});
}
And I got the error message:
TypeError: headings.snapshotItem(...) is null
There are at least 3 problems:
GM_xmlhttpRequest
's onload without a closure.links
, but trying to indexheadings
.onload
property.(1)
GM_xmlhttpRequest
operates asynchronously. Which means by the timeonload
fires that the variablesi
andheadings
will either be undefined or will be their ultimate value, not the loop value you want.To pass a value to
onload
, use a closure. (In the code below,parseURL
provides the closure.)(2) The variable
i
is looping onlinks
, but the code is trying to use it to indexheadings
! It is very unlikely that there are the same number of each (and poor practice, even if there are). Is the "heading" always a parent of the link? If so use that.Putting it all together, use code like this: