为了更详细地解释您在这里遇到问题的原因,您可能想要阅读一些关于JavaScript作用域的内容(非常有帮助的博客)。本质上,考虑以下代码:
<script>
var thisOne=true;
function thatOne() {
alert("whizbang");
}
var theOther={foo:"bar"};
</script>
一旦您到达评论部分,您就知道可以直接访问那些变量和函数,例如if (thisOne) {...}
,element.onclick=thatOne;
或 console.log(theOther.foo)
。但是,您也可以将它们作为根对象的子级来访问,在Web浏览器中称为window
。因此,您可以执行以下操作:
console.log(window["thisOne"]);
window.thatOne.call(obj, params);
console.log(window.foo.bar);
通过将open()定义为不在另一个元素内(也就是说,在根元素内),您覆盖了window.open()函数。当您尝试稍后调用该函数时,会出现问题,因为open函数调用window.open,而window.open又调用window.open,依此类推...
有几种方法可以解决这个问题 -
内联定义onclick处理程序
要做到这一点,请摆脱整个<script>..</script>
元素,然后使用任何支持它的元素添加onclick属性:
onclick="window.open('hello.jsp','window','status=1,height=700, width=800');"
这是一个不错和快速的方法,并且它将所有逻辑都与触发元素保持在一起,但是它并不容易扩展,你可能会被某些人嘲笑。(“哦,你用内联javascript? 多么古怪")
更改方法名称
从现有的代码中修改open()方法名称为openANewWindow()或gotoJSP()等不存在于根对象中的名称即可,这是花费最少的修改成本(这基本上是其他所有人建议的方法)。确保同时在定义方法(在脚本元素中)和使用方法(在onclick属性中)时都要修改。
使用闭包
对于单个函数而言,这几乎肯定不是您想要的,因为它比您需要的复杂得多。只是作为一个示例,说明如何跳出根对象,因为似乎处于根对象中是您的问题的核心。
您可能已经在JavaScript中看到了如何定义对象,但您可能不知道通过定义对象,您真正做的只是向根对象添加一个对象属性。您可以利用这种行为,给您的函数赋予分层结构。
例如:
<script>
var MyFunctions = (function() {
function open(){
var x=window.open("hello.jsp","window","status=1,height=700, width=800");
x.focus();
}
return {open:open};
})();
</script>
这将创建一个立即运行的匿名函数。在该函数的作用域内,定义了另一个函数open(),但是它是在匿名函数的作用域内定义的,而不是根对象(window)中定义的。在定义open()之后,将其引用作为对象属性open的值返回:
所有这些的结果是MyFunctions对象的open属性是您需要的函数。然后,您可以使用MyFunctions.open()或甚至window.MyFunctions.open()来调用它。