ここで問題が発生している理由を詳しく説明するために、javascript Scope(非常に役立つブログ)について少し読んでおくとよいでしょう。基本的に、次のコードを検討してください。
<script>
var thisOne=true;
function thatOne() {
alert("whizbang");
}
var theOther={foo:"bar"};
//More code here...
</script>
コメントに到達すると、、、またはのようif (thisOne) {...}
に、これらの変数と関数に直接アクセスできることがわかります。ただし、Webブラウザでは。と呼ばれるルートオブジェクトの子としてそれらにアクセスすることもできます。だからあなたはすることができます:element.onclick=thatOne;
console.log(theOther.foo)
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()が定義されていますが、ルートオブジェクト(ウィンドウ)ではなく、その無名関数のスコープ内で定義されています。open()が定義された後、それへの参照がオブジェクトプロパティの値として返されます:open。
これらすべての結果として、MyFunctionsオブジェクトのopenプロパティが必要な関数になります。次に、MyFunctions.open()またはwindow.MyFunctions.open()を使用して呼び出すことができます。