2013-01-03 2 views
0

이것은 나에게 당황 스럽습니다. 텍스트 상자가 있습니다. 뭔가를 입력하고 Enter 키를 누릅니다. Javascript는 별도의 형식으로 읽기 전용 입력 요소를 만듭니다. 나란히 텍스트 입력 상자는 그들을 제거하는 버튼입니다. 또한 해당 양식의 하단에 모든 읽기 전용 텍스트 입력을 제출하는 제출 버튼이 있습니다. 양식을 제출할 때양식 제출시 Javascript 클로저 함수가 호출되지 않습니다.

는 폼의 내부 버튼을 클릭하면 양식을 제출 (난 그냥 버튼과 해당 텍스트 입력을 모두 포함하는 부모 DIV를 제거 할) 것 때문에, 함수가 호출됩니다. 이 함수는 어떤 유형의 버튼 (제거 또는 제출)이 눌 렸는지 결정하고 그에 따라 작동합니다.

여기에 문제가 있습니다. 제거 버튼을 누르면 함수 destinations.enter이 호출되지 않습니다. 이 문제를 해결하기 위해 수행 한 작업은 submitDestinations이라는 전역 함수를 작성하여 destinations.enter의 기능을 복제하는 것입니다. 이 함수가 대신 호출되면, 모든 것이 장애없이 작동합니다.

destinations.enter이 제출시 실행되지 않는 이유는 누구입니까? submitDestinations은 누구입니까? 함수 범위가 두 함수의 유일한 차이점 인 것처럼 보이기 때문에 클로저와 관련이 있다고 믿고 싶습니다. 그러나 이것이 클로저를 처음 사용하는 경우이며 제한적으로 이해할 수 있습니다.

자바 스크립트 :

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> 

모든 것이 잘 작동합니다. 이 destinations.enter

function submitDestinations(form){ 
    var button = form.submitted; 
    if(button.id != 'submitBtn'){ 
     return destinations.remove(button); 
    }else{ 
     return true; 
    } 
} 

나는 HTML로 변경 모든과 정확히 같은 일에 호출되는 방법입니다 않습니다 제출 destinations.enter의 구현에 오류가 있습니다

 <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> 
+0

당신은 [jsfiddle] (http://jsfiddle.net)을 할 수 있을까요? 도와주는 것이 더 쉬울 것입니다. – JJJ

+0

@Juhana 어느 쪽도 jsfiddle에서 호출되지 않은 것 같습니다. http://jsfiddle.net/FcxAA/2/ –

+0

같은 문제를 보여주는 간단한 예를 생각해보십시오. 이것은 당신과 다른 사람들이 무슨 일이 일어나는지를 이해하는 데 도움이 될 것입니다. – allyourcode

답변

2

그것은 이름 지정 충돌이 있었다 밝혀졌습니다. 내가 작성한 텍스트 입력의 이름 속성은 submit시 호출했던 javascript 객체와 같은 이름 인 "대상"으로 설정되었습니다. 따라서 "onsubmit"의 javascript는 DOM 요소를 참조하고 javascript 함수를 참조하는 대신 enter를 호출하려고했습니다.

0

() . remove()를 호출하여 버튼을 제거하지만 'remove'라는 이름은 destinations.enter()가 정의 된 범위에 바인딩되지 않습니다.

destinations.remove()가 다른 곳에서 호출되지 않는 것처럼 보이므로 가장 쉬운 해결 방법은 destinations 개체의 메서드가 아닌 대상 생성자에서 전용 함수로 이동하는 것입니다. 당신이 submitDestinations의 시체를 변경 되었기 때문에

수정 된 버전은 작동() 그 범위에 바인딩 destinations.remove()를 호출합니다.

+0

아 감사합니다. 나에게 문제를 일으키는 것과는 다른 이슈였다.그것은 내가 목적지의 문제를 해결하자마자 즉시 나타 났을 것입니다. –

관련 문제