-1

我正在尝试破解一个我不拥有但我希望改进的 Web 应用程序。

我想在同域 iframe 的 DOM 元素之前添加一些 HTML。这是来自控制台的示例:

jQ(".x-panel-body.x-panel-body-noheader").find("iframe").contents().find("body").find("#WorkspaceFrame").find(".x-panel-tbar.x-panel-tbar-noheader").find(".x-toolbar-right").find(".x-toolbar-right-ct").find("table");
[
<table cellspacing=​"0">​…​&lt;/table>, 
<table id=​"ext-comp-1046" cellspacing=​"0" class=​"x-btn   x-btn-text-icon" style=​"width:​ auto;​">​…​&lt;/table>​, 
<table cellspacing=​"0">​…​&lt;/table>​, 
<table cellspacing=​"0">​…​&lt;/table>​, 
<table id=​"ext-comp-1067" cellspacing=​"0" class=​"x-btn   x-btn-text-icon " style=​"width:​ auto;​">​…​&lt;/table>​, 
<table id=​"ext-comp-1068" cellspacing=​"0" class=​"x-btn   x-btn-text-icon " style=​"width:​ auto;​">​…​&lt;/table>​, 
<table id=​"ext-comp-1069" cellspacing=​"0" class=​"x-btn   x-btn-text-icon" style=​"width:​ auto;​">​…​&lt;/table>​, 
<table cellspacing=​"0">​…​&lt;/table>​, 
<table cellspacing=​"0">​…​&lt;/table>​, 
<table id=​"ext-comp-1253" cellspacing=​"0" class=​"x-btn   x-btn-text-icon x-item-disabled" style=​"width:​ auto;​">​…​&lt;/table>​, 
<table id=​"ext-comp-1254" cellspacing=​"0" class=​"x-btn   x-btn-text-icon" style=​"width:​ auto;​">​…​&lt;/table>​, 
<table cellspacing=​"0">​…​&lt;/table>​, 
<table cellspacing=​"0">​…​&lt;/table>​, 
<table id=​"ext-comp-1760" cellspacing=​"0" class=​"x-btn   x-btn-text-icon" style=​"width:​ auto;​">​…​&lt;/table>​, 
<table cellspacing=​"0">​…​&lt;/table>​
]

jQ是我的 jQuery 的名称(我不能使用$)。

所以基本上它可以从控制台工作,并saveButton包含一个数组。这是我的脚本:

saveButton=jQ(".x-panel-body.x-panel-body-noheader").find("iframe").contents().find("body").find("#WorkspaceFrame").find(".x-panel-tbar.x-panel-tbar-noheader").find(".x-toolbar-right").find(".x-toolbar-right-ct").find("table");
console.log(saveButton);
jQ.each(saveButton, new function(i,v) { console.log("#"+i+": "+v); });

这是控制台输出:

[prevObject: b.fn.b.init[0], context: document, selector: "body #WorkspaceFrame .x-panel-tbar.x-panel-tbar-noheader .x-toolbar-right .x-toolbar-right-ct table", jquery: "1.9.1", constructor: function…]
#undefined: undefined

一个对象也是如此saveButton,但不是一个数组,这由 failed 确认jQ.each

我想拿一张桌子(总是第三张)并打电话.before('<p>something</p>')给它。我试过saveButton[2].before('<p>HI</p>')了,它不起作用。


在 Zoltan 的回答中提示后,这是一个新的尝试:

jQ(".x-panel-body.x-panel-body-noheader").find("iframe").contents().find("body").find("#WorkspaceFrame").find(".x-panel-tbar.x-panel-tbar-noheader").find(".x-toolbar-right").find(".x-toolbar-right-ct").find("table").eq(8).find(">:first-child").find(">:first-child").find(">:first-child").before('<td class="x-toolbar-cell"><button>Test</button></td>');

在控制台中键入此内容会正确添加我想要的按钮,但是 JS 代码中的同一行不起作用。是什么赋予了?

4

2 回答 2

0

您可以使用 .eq(n) 在选择中获取第 n 个对象

saveButton.eq(n).before('<p>HI</p>')

saveButton[2] 不起作用,因为这样你得到一个没有 .before 函数的普通元素,但是 .eq 返回 jQuery 包装的对象,你可以在它上面调用 jQuery 函数。

问题的根源也可能是您选择的内容位于 iframe 内。当您从控制台运行 JS 时,您处于外部窗口中,您必须“步入”iframe。但是 JS 可能会在内部窗口中运行,并且从那里运行相同的查询不会找到任何 iframe,因此不会将任何内容返回到 saveButton 变量中。

于 2013-11-07T14:12:23.063 回答
0

它在控制台中工作,因为你比用户脚本慢得多。;) 用户脚本在 iframe 完成加载之前很久就会触发,即使 iframe 不使用 AJAX 来设置内容也是如此。

解决这个问题的最简单方法是调整您的用户脚本以直接在相关 iframe 上工作,这大大简化了。

但是,由于<iframe>看起来是同一个域,您也可以使用 AJAX 页面所需的相同技术来处理该 iframe 内容。在这种情况下,waitForKeyElements实用程序效果很好。

这是一个适合您的完整脚本(但未经测试,因为我不知道目标页面)。请注意,如果您正在运行 Chrome,则需要安装 Tampermonkey(无论如何都应该这样做)来运行它。:

// ==UserScript==
// @name     _Interacting with iframed content
// @include  http://YOUR_SERVER.COM/YOUR_PATH/*
// @require  http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js
// @require  https://gist.github.com/raw/2625891/waitForKeyElements.js
// @grant    GM_addStyle
// ==/UserScript==
/*- The @grant directive is needed to work around a design change
    introduced in GM 1.0.   It restores the sandbox.
*/
waitForKeyElements (
    //-- Double check this selector from the console...
    "#WorkspaceFrame .x-toolbar-right-ct table:eq(8) >:first-child >:first-child >:first-child",
    addButton, 
    false, 
    ".x-panel-body.x-panel-body-noheader iframe"
);

function addButton (jNode) {
    jNode.before ('<td class="x-toolbar-cell"><button class="gmMyButton">Test</button></td>');
}



作为奖励,您可以像这样激活您的按钮。(需要延迟以避免竞争条件。):

waitForKeyElements (
    "body", 
    addButtonHandler, 
    false, 
    ".x-panel-body.x-panel-body-noheader iframe"
);

function addButtonHandler (jNode) {
    jNode.on ("click", "button.gmMyButton", myButtonHandler);
}

function myButtonHandler (evt) {
    var btn = $(evt.target);

    console.log ("You just clicked button '" + btn.text() + "'.");
}
于 2013-11-08T02:30:21.830 回答