我在IE中看到一些奇怪的行为,试图通过function.apply()调用另一个页面中的函数。
这是一个简单的测试用例:
test1.html:
<HTML>
<HEAD>
<script language="javascript" type="text/javascript">
var opened = null;
function applyNone() {
opened.testFunc.apply(opened);
}
function applyArgs() {
opened.testFunc.apply(opened, ["applied array"]);
}
function call() {
opened.testFunc("called directly");
}
function remoteApply() {
opened.testApply(["used remote apply"]);
}
function remoteApplyCopy() {
opened.testApplyCopy(["used remote apply copy"]);
}
function openPopup() {
opened = window.open("test2.html", "_blank");
}
</script>
</HEAD>
<BODY>
<a href="#" onclick="openPopup()">OPEN</a>
<hr>
<a href="#" onclick="applyNone()">applyNone</a>
<a href="#" onclick="applyArgs()">applyArgs</a>
<a href="#" onclick="call()">call</a>
<a href="#" onclick="remoteApply()">remoteApply</a>
<a href="#" onclick="remoteApplyCopy()">remoteApplyCopy</a>
</BODY>
</HTML>
test2.html:
<HTML>
<HEAD>
<script language="javascript" type="text/javascript">
function testApply(args) {
testFunc.apply(this, args);
}
function testApplyCopy(args) {
var a = [];
for(var i = 0; i < args.length; i++) {
a.push(args[i]);
}
testFunc.apply(this, a);
}
function testFunc() {
var s = "Got: ";
for(var i = 0; i < arguments.length; i++) {
s += arguments[i] + " ";
}
document.getElementById("output").innerHTML += s + "<BR>";
}
</script>
</HEAD>
<BODY>
Hi there
<div id="output"/>
</BODY>
</HTML>
在firefox和chrome中,所有方法都能正常工作。
在IE中(在6,7和8中测试),除了applyArgs()和remoteApply()方法之外,所有方法都按预期工作。
applyArgs()在尝试调用apply(test1.html第11行)时出现“JScript object expected”错误。
remoteApply()在尝试调用apply(test2.html第5行)时给出了相同的“JScript对象预期”错误。
问题是,我需要能够使用apply()。我可以通过执行类似remoteApplyCopy()机制来解决这个问题,但我正试图避免这种情况。为什么不适用()只是工作?
答案 0 :(得分:6)
您需要在另一个窗口中创建数组,因为每个窗口都有自己的Array构造函数。我认为这会奏效。
将此功能添加到test2.html:
function getEmptyArray() {
return new Array();
}
这个函数为test1.html:
Array.prototype.cloneToRemote = function (win) {
var newArray = win.getEmptyArray();
for (var i = 0; i < this.length; i++)
{
newArray.push(this[i]);
}
return newArray;
}
然后这样做:
function applyArgs() {
opened.testFunc.apply(opened, ["applied array"].cloneToRemote(opened));
}
注意,您似乎应该能够做到
var newArray = new win.Array();
在test1.html cloneToRemote()函数中,但我无法做到这一点。如果你能做到这一点,你可以摆脱test2.html中新的getEmptyArray()函数。
答案 1 :(得分:0)
我不知道为什么会这样,但我正在玩你的代码并偶然发现一个解决方案...把test2的函数放在test1中并且它可以工作:
<HTML>
<HEAD>
<script language="javascript" type="text/javascript">
var opened = null;
function applyArgs() {
testFunc.apply(opened, ["applied array"]);
}
function openPopup() {
opened = window.open("test2.html", "_blank");
}
function testFunc() {
var s = "Got: ";
for(var i = 0; i < arguments.length; i++) {
s += arguments[i] + " ";
}
this.document.getElementById("output").innerHTML += s + "<BR>";
}
</script>
</HEAD>
<BODY>
<a href="#" onclick="openPopup()">OPEN</a>
<hr>
<a href="#" onclick="applyArgs()">applyArgs</a>
</BODY>
</HTML>
如果我能解决的话,我会告诉你的(IE很奇怪)。就像我说的那样,我只是玩弄代码。
答案 2 :(得分:0)
如果您更改test2.html testApply()函数,如下所示:
function testApply() {
testFunc.apply(this, arguments);
}
remoteApply()有效。但是,applyArgs()仍然失败。
答案 3 :(得分:0)
” ... applyArgs()在尝试调用apply(test1.html第11行)时给出了“期望的JScript对象”错误。 remoteApply()在尝试调用apply(test2.html第5行)时给出了相同的“JScript对象预期”错误。 ......“
哪个确切的对象不是“JScript对象”为“预期”?
(提示:使用调试器)
- DBJ