2011-03-29 95 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