2012-11-14 101 views
5

我想用window.open打開一個窗口到我的一個JSP文件。但瀏覽器不斷顯示connecting..。每次點擊文本時,甚至螢火蟲都會停止工作。無論是p還是input標籤工作,但是當我使用href到JSP鏈接它可以鏈接到該文件:javascript window.open不起作用

<!DOCTYPE html> 
<html> 
<head><title>Sample JSP Page</title> 
<script> 
function open(){ 
    //window.open("hello.jsp","hello","height=700, width=800"); 
    var x=window.open("hello.jsp","window","status=1,height=700, width=800"); 
    x.focus(); 
} 
</script> 
</head> 
<body> 
<h1>Sample JSP Page</h1> 
<p onclick="open()">do not work</p> 
<form> 
<input type="button" value="new window" onclick="window.open('test-with-utils')"></form> 
</body> 
</html> 
+2

可能希望將它的open()函數重命名爲與window.open()相同的作用域() – Neps

回答

10

那是因爲你已經重新定義window.open當你定義的開放功能。改用其他函數名稱。

+0

非常聰明!我花了一些時間處理類似的問題。謝謝! – rigon

+0

拯救生命。剛剛碰到這個:P –

5

window對象是JavaScript中的頂級對象,幷包含在自身其他幾個對象,如「文件」,「歷史」等

當你定義一個變量或您自己的函數你真的爲窗口對象添加一個新的屬性。而這將工作(和一點點活example):

var foo = "bar"; 
alert (window.foo); // says "bar" 

此外,如果你加入這個小片段到您的代碼:

window.onerror = function (msg, url, num) { 
    alert ("Error: " + msg + "\nURL: " + url + "\nLine: " + num); 
    return true; 
}; 

你會得到這個錯誤,當按下按鈕:

Error: Uncaught RangeError: Maximum call stack size exceeded 

這意味着無限的遞歸。這是一個副作用 - 你定義了一個新的開放函數,當你調用window.open()時,你遞歸地調用你的函數。

+0

+1好解釋 – prageeth

1

爲了擴大您在這裏遇到問題的原因,您可能需要閱讀一些有關JavaScript範圍(Very Helpful Blog)的信息。從本質上講,考慮下面的代碼:

<script> 
var thisOne=true; 
function thatOne() { 
alert("whizbang"); 
} 
var theOther={foo:"bar"}; 

//More code here... 
</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()函數。當您稍後嘗試調用該函數時,會出現問題,因爲打開的函數調用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(),但是它在該匿名函數的範圍內定義,而不是根對象(窗口)。在定義open()之後,對它的引用作爲對象屬性的值返回:open。

所有這些的結果是MyFunctions對象的打開屬性是您需要的功能。然後你可以用MyFunctions.open()甚至window.MyFunctions.open()來調用它。