我遇到与iframe相关的问题。
我有一个iframe(child)的文档(父级)。如果父文档调用子项中的一个函数,该函数使用window.location将子URL更改为相对URL,则该url将变为相对于父文档。让我来说明一下。
父文件:/test/parent.html
子文档:/projects/child.html
子代码:
function moveOn(){
window.location.href = "newPage.html";
}
家长代码:
childDocument.contentWindow.moveOn();
结果: 子文档尝试访问 /test/newPage.html 而不是 /projects/newPage.html
有没有办法解决这个问题?我处于这样一种情况:我无法在子文档代码中进行更改,只能在父文档中进行更改。
谢谢, NIK
编辑:
这是实际代码
在父级(/testr/testr.html)中:
testr.appHolder = $("childIframe");
testr.appHolder.src = "../projects/test.html";
testr.functionName = "moveOn";
testr.appHolder.contentWindow[testr.functionName]();
在孩子(/projects/test.html)中:
function moveOn(){
window.location.href = "newPage.html";
}
这是实际代码
在父级(/testr/testr.html)中:
testr.appHolder = $("childIframe");
testr.appHolder.src = "../projects/test.html";
testr.functionName = "moveOn";
testr.appHolder.contentWindow[testr.functionName]();
在孩子(/projects/test.html)中:
function moveOn(){
window.location.href = "newPage.html";
}
答案 0 :(得分:4)
最后,一个完整的解决方案!
childDocument.contentWindow.setTimeout( childDocument.contentWindow.moveOn, 0 );
这要求子文档在零毫秒内执行给定的函数(moveOn
),并且它在子上下文中执行,即使在Internet Exploder中也是如此。
Booyah。
答案 1 :(得分:-1)
HTML规范说:
当设置[location属性]时,[browser]必须相对于条目脚本的基本URL解析参数,如果成功,则必须将浏览上下文导航到指定的URL。
获得您所追求的行为的一种(hacky)方式是直接编辑pathname
的{{1}}属性:自己有效地实现相对网址的解析。
在您的情况下,您可以使用您孩子的现有网址“手动”编辑网址。
Dotdot解决方案
一种“聪明”的方法是通过附加一个斜杠将文件名转换为“目录”,然后用“dotdot”删除它,然后是你想要的相对网址。
location
(此代码也适用于孩子,但你提到你无法更改子代码。)
了解其工作原理。
路径以<childDocument.contentWindow.location.pathname += "/../newPage.html";
然后你附加它,得到
/projects/child.html
浏览器将此解析为
/projects/child.html/../newPage.html
不幸的是,我想这对你来说不是一个完美的解决方案。听起来每个“子”页面都包含指向链中下一页的硬编码链接,可以是任何页面。获取任何给定子页面的“下一个”相对URL将需要孩子的合作。
如果子页面以可预测的方式命名,并且您知道页面总数,并且您知道子目录的基本URL,则可以让父控件正确控制子项。那是很多ifs。
旁注:我正在研究一种更优雅,更强大的解决方案。手指交叉。
答案 2 :(得分:-1)
啊哈。我找到了baseURI
属性。现在我们正在谈论。
基本问题是执行代码(父代)的文档的baseURI
被设置为父代的位置。您希望在更改页面的位置之前将页面的baseURI设置为与子项目的位置相同,以便在子项的上下文中解析相对URL。
简而言之,可以说:
var originalURI = document.baseURI; // store for setting back after the move
document.baseURI = childDocument.location; // setting parent's baseURI (NO EFFECT!)
childDocument.contentWindow.moveOn();
document.baseURI = originalURI; // restore original baseURI
不幸的是,baseURI
属性只读。幸运的是,它的值来自<base>
标记,您可以使用脚本进行更改。您可以通过将父级的基本标记设置为引用childUrl来获取给定子级所需的功能:
<head>
<base href="/path/to/child.html" />
</head>
不幸的是,这使得父母相对于孩子的任何相对链接,这不是你想要的。我们需要在点击链接后立即设置,并在将孩子告知moveOn()
后将其设置回来。
如果您在父级<base />
中添加了空<head>
标记,则默认情况下不会影响baseURI。因此,当您想要在子项中执行moveOn()
函数时,您可以这样说:
var baseElement = document.getElementsByTagName("base")[0];
// adopt the child's location as baseURI
baseElement.href = childDocument.location;
childDocument.contentWindow.moveOn();
// revert back to the parent's original baseURI
baseElement.removeAttribute("href");
(希望这会有所帮助 - 两年后......哈哈)
修改强>
互联网爆炸者再一次成为派对的一员。似乎加载后对任何标记的更改都不受尊重。因此,除非您不必支持IE(HA!),否则此解决方案将无效,除非您乐意将子位置硬编码到父级标记中。再一次,这些都很重要。