2011-05-08 45 views
1

我正在写一个greasemonkey脚本。最近我有两次这个相同的问题,我不知道为什么会发生这种情况。发生了什么?有一天它可以,第二天它的'未定义'?

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。注意,几天前,我已经完全按照相同的方式进行了测试,并且根本没有这样的问题。

好了,所以,我决定重新命名oPriorityoPriorityMass。神奇的是,问题解决了。

起初我想,也许有一些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没有任何影响,因为当我调整浏览器大小时它保持不变。

EDIT2

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次重试,可能会有所不同还有其他事情要做吗?

+0

是'node.childNodes [c]'未定义,或者它是'node.childNodes [c] .getAttribute('coll')'(等),这是未定义的? ...该网页是否被任何** JavaScript修改? ......我们将需要一个特定的故障配方或链接到完整的脚本代码来帮助更多地了解这一点。 – 2011-05-08 07:20:11

+0

我编辑了我的帖子,我希望它现在提供更多信息。 try-catch块返回与没有try-catch块完全相同的错误。 – user1651105 2011-05-08 10:28:21

+0

第一次遇到该行或在多次循环之后抛出异常吗?有没有可能儿童从0开始没有顺序编号? – Basic 2011-05-08 10:31:41

回答

0

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

在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 

无论哪一个适合,并且更易于维护。

0

那么,根据你上次的编辑,它现在的作品,延迟,对吗?

但是,当我提出延迟时,它并不意味着在等待的时候(甚至更多?)ajax调用!

if (!oPriorityMass.childNodes[0]) { 
    GM_log('Retrying'); 
    setTimeout(loadPage,2000); 
    return; 

更多类似:

setTimeout (colli, 2000); 

所以AJAX和其他的东西,loadPage确实可以解释过度延迟。


随机行为可以由以下原因引起:

return top.document.getElementById(ns(sID)); 

这将导致不稳定的行为,如果任何框架或iFrame都存在,你不帧块操作。 (如果你阻止这样的操作,那么top是多余的和不必要的。)
GM在这种情况下不能正确操作 - 取决于脚本的作用 - 常常看起来从顶部范围“切换”到帧范围或反之亦然。

因此,它可能是最好的改变,为:

return document.getElementById (ns (sID)); 


并确保您有:

if (window.top != window.self) //-- Don't run on frames or iframes 
    return; 

为代码的顶部线条。


除此之外,它几乎是不可能看到,因为信息不足的问题。

要么熬问题转化为完整自给式配方的复制失败。

OR,张贴或链接到完成未经编辑的脚本

+0

我无法发布我的脚本。我相信你对操纵页面内容的东西是正确的。延迟并不总是有效。解决这个问题的方法是直接列出我需要的元素,而不用像'element.childNode [x]'这样的东西。我将类添加到我需要的元素中,然后通过自定义'document.getElementsByClass'将这些元素添加到数组中,它运行良好。 – user1651105 2011-06-22 11:37:17

相关问题