2012-01-10 35 views
3

我正在创建一个Greasemonkey脚本,以便在我们的在线票务系统中自动设置一些选项,以便使日志记录调用更有效。使用Greasemonkey脚本在框架中调用函数

无论如何,记录呼叫的屏幕是由多个帧组成的,在自动化方面我只感兴趣一个。为页和框架(包括我想编辑的元素)的剥离下来的HTML显示如下:

<html> 
<head> 
</head> 
<frameset framespacing="0" border="0" bordercolor="#ffffff" rows="130,*,22,0"> 
    <frame scrolling="no" marginwidth="0" marginheight="0" leftmargin="0" topmargin="0" noresize="" src="top.asp?menu=&page=" name="menu"> 
    </frame> 
    <frameset id="contentCols" framespacing="8" border="8" cols="250, *" bordercolor="#ffffff"> 

     <frame marginwidth="0" marginheight="0" leftmargin="0" topmargin="0" border="0" src="../service/loading.html" name="content" frameborder="0" style="padding-right: 10px;"> 
      <html> 
      <head> 
      </head> 
      <body class="winBack" style="background-color: rgb(255, 255, 255);"> 

      <div id="scrollableContainer" class="lockedTableContainer scrollableContainerHeight" style="position: relative; height: 0px;"> 

      <table cellspacing="1" cellpadding="3" border="0"> 
      <form id="configFields" name="configFields" method="post" action="/ics/tt/ticketNew.asp"></form> 
       <input type="hidden" value="" name="task"> 
       <input type="hidden" value="account" name="source"> 
       <tbody> 
       <tr id="ROW_109094"> 
        <td class="webCaption" style="width: 160px;"> 
        </td> 

        <td class="formText"> 
         <select id="FIELD_109094_DROPDOWN_null" class="formText" style="width: 200px;" title="Establishment Type" name="FIELD_109094_DROPDOWN_null" onchange="updateDep(109094, this.options[this.selectedIndex].value);"> 
         </select> 
        </td> 
       </tr> 
       </tbody> 
      <table> 
      </div> 
     </frame> 
    </frameset> 
</frameset> 
</html> 


我所试图做的是设置FIELD_109094_DROPDOWN_null选择元素的selectedIndex
然后,我试图运行连接到该元素的change事件的updateDep函数(该函数包含在附加到框架的脚本中);此功能根据select元素中当前设置的值显示某些其他字段。

用Firebug的控制台,我可以做到这一点使用下面两行:

frames["content"].document.getElementById("FIELD_109094_DROPDOWN_null").selectedIndex = 2; 
frames["content"].updateDep(109094, frames["content"].document.getElementById("FIELD_109094_DROPDOWN_null").options[2].value); 

然而,当我把它变成的Greasemonkey脚本,并将其安装到任何主窗口的onload,或帧的onload;我得到这个错误:

Error: frames.content.document.getElementById("FIELD_109094_DROPDOWN_null") is null

如果我用,下面的代码但是,我至少可以改变选择元素的选择指标:

document.getElementById("FIELD_109094_DROPDOWN_null").selectedIndex = 2; 

我无法弄清楚如何通过运行updateDep功能Greasemonkey脚本。脚本中的代码如下所示:

// ==/UserScript== 

var initElements = (function() { 

    var elementExists = document.getElementById("FIELD_109094_DROPDOWN_null"); 

    if(elementExists) 
    { 
     document.getElementById("FIELD_109094_DROPDOWN_null").selectedIndex = 2; 
     frames["content"].updateDep(109094, frames["content"].document.getElementById("FIELD_109094_DROPDOWN_null").options[2].value); 

    } 
} 
)(); 

window.addEventListener('load', initElements, false); 

任何帮助将不胜感激。

回答

1

框架和iFrames的诀窍是它们看起来像Greasemonkey的单独页面。

因此,对于问题中的HTML,GM脚本可能最终运行3次,具体取决于@include,@exclude和/或@match指令的配置方式。

因此,取决于脚本循环通过的运行,相同的元素将会以不同的方式出现(或根本不相同)。因此,除非您正确知道/控制脚本的执行状态,否则请不要使用类似frames["content"]的代码。有条件地测试节点并运行代码更好。

另一件事是,当使用驻留在目标页面上的JavaScript时,您需要使用unsafeWindow或解决方法。

全部放在一起,像这样的代码应该工作:

var depSelect = document.querySelector ("#FIELD_109094_DROPDOWN_null"); 
if (depSelect) { 
    depSelect.selectedIndex = 2; 
    unsafeWindow.updateDep (109094, depSelect.options[2].value); 
} 

(假设没有滑稽的生意与@include@exclude,和/或@match指令。)

你不应该需要window.addEventListener('load'...东西,也不包装在initElements()代码。

+0

嘿布洛克,这个完美工作,谢谢我真的很感激。 – achillesminor 2012-01-11 10:32:34

+0

不客气。乐意效劳。 – 2012-01-11 12:36:20

0

我创立了通用汽车不按名称帧识别。我得到我的脚本工作的唯一方法是使用框架索引而不是名称。

frames[2].document... 

,而不是

frames['aname'].document...