これは私を困惑させました。私はテキストボックスを持っています。何かを入力して、Enter キーを押します。Javascript は、別のフォームで読み取り専用の入力要素を作成します。テキスト入力ボックスの横には、それらを削除するためのボタンがあります。そのフォームの下部には、すべての読み取り専用テキスト入力を送信するための送信ボタンもあります。
フォーム内のボタンをクリックするとフォームが送信されるため (ボタンとそれに対応するテキスト入力の両方を含む親 div を削除したいだけです)、フォームの送信時に関数が呼び出されます。この関数は、押されたボタンのタイプ (削除または送信) を判別し、それに応じて動作します。
ここで問題が発生します。削除ボタンが押されたとき、関数destinations.enter
は決して呼び出されません。これを解決するために私がしたことはsubmitDestinations
、 の機能を複製する と呼ばれるグローバル関数を作成することでしたdestinations.enter
。代わりにこの関数を呼び出すと、すべて問題なく終了します。
なぜdestinations.enter
送信時に実行されないのか、誰にも考えがありsubmitDestinations
ますか? 関数スコープが2つの関数の唯一の違いであるように見えるので、クロージャーと関係があると信じたいです。ただし、クロージャーを使用するのはこれが初めてであり、クロージャーについての理解は限られています。
Javascript:
var destinations = (function(){
var max_destinations = 7;
var counter = 0;
function increment(){
counter += 1;
if(counter > max_destinations){
throw 'Too many destinations. (Max 7)'
}
}
function decrement(){
counter += 0;
if(counter < 0){
alert('Cannot have less than 0 destinations..')
throw 'Too few destinations. Get out of the console!'
}
}
return {
add : function(form){
try{
var formInput = form.elements[0];
var destination = formInput.value;
// Dont do anything if the input is empty
if(destination == ""){
return false;
}else{
// increment the destinations counter
increment();
}
}catch(err){
alert(err);
return false;
}
// add the text value to a visual element
var elem = document.createElement('div');
elem.setAttribute('class','destination');
// create the input
var input = document.createElement('input');
input.setAttribute('id','dest'+String(counter));
input.setAttribute('class','destinationText');
input.setAttribute('style','border: none');
input.setAttribute('name','destinations');
input.setAttribute('readonly','readonly');
input.setAttribute('value',destination);
// create the remove button
var button = document.createElement('button');
button.setAttribute('onclick','this.form.submitted=this;');//'return destinations.remove(this);');
button.setAttribute('class','removeButton')
button.setAttribute('id','but'+String(counter))
var buttonText = document.createTextNode('Remove');
button.appendChild(buttonText);
// add the elements to the div
elem.appendChild(input);
elem.appendChild(button);
var parent = document.getElementById('destinationsDiv');
parent.appendChild(elem);
// clear the input box
formInput.value = '';
return false;
},
enter : function(form){
alert('hi')
var button = form.submitted;
if(button.id != 'submitBtn'){
return remove(button);
}else{
return true;
}
return false;
},
remove : function(button){
try{
decrement();
}catch(err){
// do not allow less than 0 counter
alert(err);
return false;
}
// remove the button's parent div altogether
var toDelete = button.parentNode;
toDelete.parentNode.removeChild(toDelete);
return false;
}
}
})();
そしてhtml:
<div>
<form id='hi' onsubmit="return destinations.add(this);">
<input type="text" value="" />
</form>
<!--form id='submitDiv' method="post" onsubmit="alert(this.submitted);return submitDestinations(this);"-->
<form id='submitDiv' method="post" onsubmit="alert(this.submitted);return destinations.enter(this);">
<div id='destinationsDiv'>
<div>
<input id="dest1" class="destinationText" style="border: none" name="destinations" readonly="readonly" value="aadasd" \>
<button onclick="this.form.submitted=this;" class="removeButton" id="but1" \></button>
</div>
<div>
<input id="dest2" class="destinationText" style="border: none" name="destinations" readonly="readonly" value="Hi Stackoverflow" \>
<button onclick="this.form.submitted=this;" class="removeButton" id="but2" \></button>
</div>
</div>
<input type="submit" id='submitBtn' onclick="this.form.submitted=this;"/>
</form>
</div>
次の JavaScript 関数をグローバル スコープに追加して代わりに呼び出すと、すべて正常に動作します。これは、次とまったく同じことを行いますdestinations.enter
function submitDestinations(form){
var button = form.submitted;
if(button.id != 'submitBtn'){
return destinations.remove(button);
}else{
return true;
}
}
HTML で変更するのは、送信時に呼び出されるメソッドだけです。
<div>
<form id='hi' onsubmit="return destinations.add(this);">
<input type="text" value="" />
</form>
<form id='submitDiv' method="post" onsubmit="alert(this.submitted);return submitDestinations(this);">
<!--form id='submitDiv' method="post" onsubmit="alert(this.submitted);return destinations.enter(this);"-->
<div id='destinationsDiv'>
<div>
<input id="dest1" class="destinationText" style="border: none" name="destinations" readonly="readonly" value="aadasd" \>
<button onclick="this.form.submitted=this;" class="removeButton" id="but1" \></button>
</div>
<div>
<input id="dest2" class="destinationText" style="border: none" name="destinations" readonly="readonly" value="Hi Stackoverflow" \>
<button onclick="this.form.submitted=this;" class="removeButton" id="but2" \></button>
</div>
</div>
<input type="submit" id='submitBtn' onclick="this.form.submitted=this;"/>
</form>
</div>