2011-03-29 41 views
2

我有一個奇怪的問題。 我嘗試編寫一個GreaseMonkey腳本,以便在Firefox和Google Chrome中運行。 在Chrome中,我嘗試了兩個擴展名:「TamperMonkey」和「空白畫布腳本處理程序」,主要是因爲我的腳本在外部網站上對新版本進行了定期檢查,這被認爲是跨站點腳本,未經Chrome授權。Chrome無法讀取style.display值

要告訴你我的問題,我寫了一個簡單的測試案例:

// ==UserScript== 
// @name  test 
// @namespace  http://fgs.ericc-dream.fr.nf 
// @description  test gm script 
// @include   http://gaia.fallengalaxy.eu/ 
// @author   ericc 
// @version   0.0.1 
// ==/UserScript== 

/* We attach an event listener to the body tag and trigger the function 
* 'message' each time that an element is inserted in the page */ 
var el = document.body; 
el.addEventListener('DOMNodeInserted', message, false); 

var extraFlag = false; 

function message(event) { 
    /* first we capture the id of the new inserted element 
    * (the one who created the event) */ 
    var objId = event.target.id; 

    /* add an event listener on the map container */ 
    if (objId == "extra") { 
     el = document.getElementById('extra'); 
     el.addEventListener('DOMSubtreeModified',readTest,false); 
     GM_log(el.style.display); 
    } 
} 

function readTest() { 
    el = document.getElementById('extra'); 
    GM_log(extraFlag); 
    GM_log(el.style.display); 
    if ((el.style.display != 'none') && (!extraFlag)) { 
     alert('extra'); 
     extraFlag = true; 
    } else if ((el.style.display == 'none')) { 
     extraFlag = false; 
    } 
} 

的div元素「額外」通過網頁進行修改。問題在於Chrome無法讀取el.style.display的值,因此extraFlag再也不會變成'false'。 我使用這個標誌避免了幾次運行代碼,該網站是嚴重的JavaScript驅動 這段代碼在Firefox中很好地工作!

我試圖用Google搜索但找不到正確的答案。似乎很容易改變顯示的價值,但似乎我是唯一一個試圖閱讀它的人!

我寫這個代碼,因爲「DOMAttrModified」是在Chrome事先不支持:-(

感謝您的幫助

ericc

回答

3

我有一個很難理解到底是什麼您的問題是,但它看起來像Chrome可以讀取.style.display屬性就好了。我只是將以下代碼投射到HTML模板並將其加載到Chrome 10中:

<div id="div1"> 
</div> 

<div id="div2" style="display: block;"> 
</div> 

<div id="div3" style="display: inline;"> 
</div> 

<div id="div4" style="display: none;"> 
</div> 

<script type="text/javascript"> 
    alert(document.getElementById("div1").style.display); 
    alert(document.getElementById("div2").style.display); 
    alert(document.getElementById("div3").style.display); 
    alert(document.getElementById("div4").style.display); 

    document.getElementById("div1").style.display = "none"; 

    alert(document.getElementById("div1").style.display); 
</script> 

的代碼生成與以下輸出5 '警報' 框:

  • 直列
  • 沒有
  • 沒有

如此看來丁目讀取這個屬性就好了。

也許問題在於,運行您的greasemonkey腳本的網頁在Chrome中的行爲與在Firefox中的行爲不同?難道是這個元素的ID是不同的,或者這個元素是從DOM中刪除而不是被隱藏起來?如果你用更多的檢查修改你的函數會發生什麼,有點像這樣?

function readTest() { 
    el = document.getElementById('extra'); 
    if(el) 
    { 
     GM_log(extraFlag); 
     GM_log(el.style.display); 
     if (el.style.display && (el.style.display != 'none') && (!extraFlag)) { 
      alert('extra'); 
      extraFlag = true; 
     } else if ((el.style.display == 'none') || !el.style.display) { 
      extraFlag = false; 
     } 
    } 
    else 
    { 
     GM_log(extraFlag); 
     GM_log("element not present"); 
     extraFlag = false; 
    } 
} 

這有幫助嗎?如果沒有,您是否還有其他理由可以考慮爲什麼el.style.display無法在Chrome中正確評估?

如果我們知道更多關於您想要對您的腳本進行什麼操作的知識,可能會有所幫助,並且可能還有您想要運行的網頁或代碼。

1

幾個小時,一噸的測試案例之後,我終於找到一個可以接受的解釋(但尚未解決!)

讓我們來解釋一下情景:
1°)上的一個圖標,用戶點擊屏幕
2°)已經存在於頁面中的div#extra通過刪除其顯示屬性(.style)變得可見。)#
3°)div#extra由AJAX函數歸檔,其中某些元素取決於用戶點擊了哪個圖標(在某些情況下超過200個元素)
4°)用戶單擊另一個圖標來關閉div
5°)除去div#extra中的所有元素
6°)div#extra被display屬性隱藏爲'none'(.style.display =「none」 )

起初,在Firefox,我用在DIV#額外檢查當顯示屬性被修改並相應地做出反應「DOMAttrModified」事件。 問題,Chrome不支持此事件!

所以我用「DOMSubtreeModified」替換(連接到的div#額外的),這是由瀏覽器都支持....但不完全以同樣的方式:-(
在Firefox,觸發一個事件對於子樹中的每一個修改,但是當元素本身被修改時也是如此
在Chrome瀏覽器上,它們更加嚴格一些,並且觸發事件僅適用於子樹中的修改....這是我的問題!

在Firefox中,第一個事件在第2點(在場景中)觸發,最後在第6點,允許我的函數在div#extra被隱藏時讀取

在Chrome中,第一個事件在第3點被觸發,最後在第5點......所以當div#extra被隱藏時,我的函數沒有被調用,我不能修改該標誌! CQFD

現在,或者我將添加一個事件監聽器到頁面的主體來攔截當顯示屬性被修改時,但它會產生大量的函數調用,或者TamperMonkey的開發者昨天說他的擴展現在支持「DOMAttrModified」(在Chrome)....

還是要謝謝你花時間來了解我的問題,你提出的解決方案

ericc

+0

有關問題的其他信息不應該作爲答案發布。編輯您的原始問題以包含此信息。 – 2011-03-31 13:27:55