Зацикливание GM_xmlhttpRequest дает TypeError Null для переменной

У меня есть несколько ссылок на странице. Я хочу подсчитать ответы каждой ссылки и вставить числа перед ссылками. Вот что у меня есть:

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

И я получил сообщение об ошибке:

TypeError: headers.snapshotItem(...) имеет значение null


person wonderful93    schedule 02.07.2013    source источник


Ответы (1)


Есть как минимум 3 проблемы:

  1. Попытка передать значение для загрузки GM_xmlhttpRequest без закрытия.
  2. Зацикливается на links, но пытается проиндексировать headings.
  3. Отсутствует двоеточие после свойства onload.

(1) GM_xmlhttpRequest работает асинхронно. Это означает, что к моменту запуска onload переменные i и headings либо будут неопределенными, либо будут их окончательным значением, а не значением цикла, которое вы хотите.

Чтобы передать значение onload, используйте замыкание. (В приведенном ниже коде parseURL обеспечивает закрытие.)

(2) Переменная i зацикливается на links, но код пытается использовать ее для индексации headings! Очень маловероятно, что их будет одинаковое количество (и плохая практика, даже если они есть). Всегда ли «заголовок» является родителем ссылки? Если это так, используйте это.

Собрав все вместе, используйте такой код:

var links = document.evaluate (
    '..../td[1]/font//a[@href]', document, null, 
    XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null
);
//-- "Headings" are relative to links

for (var J = links.snapshotLength - 1;  J >= 0;  --J) {
    var targUrl = links.snapshotItem (J).href;
    parseURL (targUrl, J);
}

function parseURL (targUrl, J) {
    GM_xmlhttpRequest ( {
        method: 'GET',
        url:    targUrl,
        onload: function (res) {
            var dt = document.implementation.createDocumentType (
                "html", "-//W3C//DTD HTML 4.01 Transitional//EN", 
                "http://www.w3.org/TR/html4/loose.dtd"
            );
            var doc         = document.implementation.createDocument ('', '', dt);
            var 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>';

            var heading     = links.snapshotItem (J).parentNode.parentNode;
            heading.parentNode.insertBefore (numResponse, heading);
        }
    } );
}
person Brock Adams    schedule 02.07.2013
comment
Еще один вопрос, после того, как я добавлю эти цифры на страницу. Страница загружается очень медленно. Можно ли как-то ускорить? run-at document-start может выполнять код до загрузки страницы, но у меня все еще есть кое-что для запуска в конце документа. - person wonderful93; 08.07.2013
comment
Возможно, вам придется открыть новый вопрос. В общем: убедитесь, что GM_xmlhttpRequest не используется в режиме синхронизации (по умолчанию он выключен); убедитесь, что вы не работаете в фреймах без необходимости; ограничить обрабатываемые ссылки; запускать скрипт после загрузки окна; Не используйте XPath для результатов AJAX. - person Brock Adams; 09.07.2013