我正在写一个润滑脂脚本。最近我两次遇到同样的问题,我也不知道为什么会这样。

function colli(){
.....
var oPriorityMass = bynID('massadderPriority');//my own document.getElementById() function
var aPriorities = [];
if (oPriorityMass) {
    for (var cEntry=0; cEntry < oPriorityMass.childNodes.length; cEntry++) {
        var sCollNumber = oPriorityMass.childNodes[cEntry].getAttribute('coll');
        if (bynID('adder' + sCollNumber + '_check').checked)
            aPriorities.push(parseInt(sCollNumber));
    }
}
.....
}


因此,有一个谜是,有一天我将oPriorityMass命名为oPririoty。它工作正常,但整个功能尚未完成,我开始为脚本编写其他功能。这些功能彼此之间没有联系。

几天后,我决定返回上述示例中的功能并完成它。我在不做任何修改的情况下对其进行了测试,并在Firefox的(4)javascript错误控制台中收到一条错误消息,提示oPriority.chilNodes[cEntry] is undefined。注意,几天前我已经以完全相同的方式对其进行了测试,并且根本没有这样的问题。

好的,所以,我决定将oPriority重命名为oPriorityMass。神奇地,问题解决了。

起初我以为,也许2个对象存在一些冲突,但在不同的函数中使用了相同的名称,即使在函数范围之外,它们仍然以某种方式继续存在。我的脚本当前超过6000行,但是我进行了一次搜索,发现在这个确切的函数中没有提到oPriority

有人可以告诉我,这是怎么回事,为什么呢?我提到同一件事发生了两次,它们发生在不同的函数中,但是相同的问题node.childNodes[c] is undefinednode不为null,并且node.childNodes.length显示正确的子计数。
到底是怎么回事?我如何避免此类问题?

谢谢

编辑:错误控制台给出的错误是
Error: uncaught exception: TypeError: oPriorityMass.childNodes[cEntry] is undefined

回应Brocks评论:
GM_log(oPriorityMass.childNodes[cEntry])返回undefined作为消息。因此,node.childNodes[c]通常是未定义的东西。

我的脚本创建了一个div窗口。稍后,以上函数在此div中使用元素。元素确实具有唯一的ID,我100%确信原始网站对此一无所知。
我的脚本有一个开始/停止按钮,可以在需要时运行一个或另一个功能。
我一直在刷新页面并现在运行我的脚本功能。我注意到有时(但并非总是)脚本在第一次运行时会因描述的错误而失败,但是,如果我再次运行它(不刷新页面),它将开始工作。

该页面具有可对其进行修改的JavaScript。它会更改某些元素的宽度,因此在调整浏览器大小时会更改。但是我知道它对我的div没有影响,因为当我调整浏览器大小时它保持不变。

编辑2:

function bynID(sID) {
    return top.document.getElementById(ns(sID));
}
function ns(sText) {
    return g_sScriptName + '_' + sText;
}


ns函数只是在ID前面添加脚本名称。我在创建HTML元素时使用它,因此我的元素永远不会具有与网页相同的ID。因此,bynID()是一个简单的函数,可以在我需要通过ID获取元素时节省一些键入时间。

我已经修改了我的colli()函数以包括检查

if (oPriorityMass) {
    if (!oPriorityMass.childNodes[0]) {
        GM_log('Retrying');
        setTimeout(loadPage,2000);
        return;
    }
    for (var cEntry=0; cEntry < oPriorityMass.childNodes.length; cEntry++) {
        var sCollNumber = oPriorityMass.childNodes[cEntry].getAttribute('coll');
        if (bynID('adder' + sCollNumber + '_check').checked)
            aPriorities.push(parseInt(sCollNumber));
    }
}


loadPage函数执行1个AJAX调用,然后在其上运行一些XPATH查询,但是实际内容从未添加/显示在页面上,仅保存在document.createElement('div')内部,然后此函数调用colli()。因此,现在,当我修改功能时,我检查了错误控制台,发现可能最多需要5次尝试才能使其开始正常工作。 5 x 2秒,即10秒。永远不会进行5次重试,可能会有所不同还有其他事情要做吗?

最佳答案

在Firefox中,childNodes可以包含#text节点。在尝试调用childNodes[cEntry]之前,应确保它具有nodeType == 1或具有getAttribute方法。例如

<div id="d0">
</div>
<div id="d1"></div>


在Firefox和类似浏览器中(即基于Gecko和基于WebKit的浏览器,例如Safari)中,d0具有一个子节点,一个文本节点,而d1没有子节点。

所以我会做类似的事情:

var sCollNumber, el0, el1;

if (oPriorityMass) {
    for (var cEntry=0; cEntry < oPriorityMass.childNodes.length; cEntry++) {
        el0 = oPriorityMass.childNodes[cEntry];

        // Make sure have an HTMLElement that will
        // have a getAttribute method
        if (el0.nodeType == 1) {
          sCollNumber = el0.getAttribute('coll');
          el1 = bynID('adder' + sCollNumber + '_check');

         // Make sure el1 is not falsey before attempting to
         // access properties
         if (el1 && el1.checked)

            // Never call parseInt on strings without a radix
            // Or use some other method to convert to Number
            aPriorities.push(parseInt(sCollNumber, 10));
    }
}


鉴于sCollNumber似乎是一个字符串整数(只是猜测,但似乎很有可能),您还可以使用:

Number(sCollNumber)


要么

+sCollNumber


两者比较合适且更易于维护。

关于javascript - 发生了什么?一天是开,第二天是“未定义”?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5926075/

10-12 06:59