2011-05-08 36 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

相關問題