2012-02-08 3 views
0

조금 이상한 노력하는 것은 내가 무엇을했는지 있습니다 :드롭 다운의 변경 핸들러가 여기에

<html><head><script type="text/javascript"> 
function loaded(){ 
    var selectElems=document.getElementsByName("select"); 
    for(i=0;i<selectElems.length;i++){ 
     var elem=selectElems[i]; 
     elem.onchange=function(){ 
      alert(elem.selectedIndex); 
     } 
    } 
} </script></head> 
<body onload="loaded()"> 
<select name="select"> 
     <option>0</option> 
     <option>1</option> 
     <option>2</option> 
     <option>3</option> 
     <option>4</option> </select> 
<select name="select"> 
     <option>0</option> 
     <option>1</option> 
     <option>2</option> 
     <option>3</option> 
     <option>4</option></select> 
<select name="select"> 
     <option>0</option> 
     <option>1</option> 
     <option>2</option> 
     <option>3</option> 
     <option>4</option></select> 
</body></html> 

내가 자바 스크립트 요소의 인덱스를 선택하는 데 필요한. 그러나 나는 그것에 문제가있었습니다. http://jsfiddle.net/aRMpt/139/

답변

3

문제는 당신 elem는 항상 마지막 select 요소를 가리키는 것입니다 : 다음은 내 코드입니다. 가장 간단한 해결 방법이 정말 문제가 있지만 무엇인지 말해주지 않습니다 http://jsfiddle.net/mendesjuan/aRMpt/140/

function loaded(){ 
    var selectElems=document.getElementsByName("select"); 
    for(i=0;i<selectElems.length;i++){ 
     var elem=selectElems[i]; 
     elem.onchange=function(){ 
      // This points to the select element that was changed 
      alert(this.selectedIndex); 
     } 
    } 
} 

ELEM 변수 대신 핸들러에서 this을 사용하는 것입니다. 그것은 좋은 해결책이지만 해결 방법입니다. 코드가 작동하지 않는 이유는 클로저 함수 onchange이 클로저의 동일한 elem을 사용하기 때문입니다. onchange이 호출 될 때까지 elem은 마지막으로 select 요소를 가리 킵니다. 이를 방지하기위한 방법은 가 여기에 위의 예제가 작동하는 방법을 이해하는 데 도움이 수있는 또 다른 예입니다 귀하의 onchange를 핸들러 http://jsfiddle.net/mendesjuan/aRMpt/142/

function loaded(){ 
    var selectElems=document.getElementsByName("select"); 
    for(i=0;i<selectElems.length;i++){ 
     var elem=selectElems[i]; 
     // Freeze the elem variable by creating a function that passes 
     // the elem and creates a separate closure for each handler 
     elem.onchange= (function(el) { 
      // This is the function that will actually be the handler 
      return function(){ 
      // This points to the select element that was changed 
      alert(el.selectedIndex); 
      } 
    }) (elem) 
} 

에 대한 ELEM을 정지 또 다른 폐쇄를 소개하는 것입니다.

// This is a function that returns another function 
// Its only reason is so that we don't use the shared closure 
// variables from the outer scope, it freezes the el 
// variable at the moment its called and so that it's available 
// when the handler is called 
function createOnChangeHandler(el) { 
    return function() { 
    alert(el.selectedIndex); 
    } 
} 

function loaded(){ 
    var selectElems=document.getElementsByName("select"); 
    for(i=0;i<selectElems.length;i++){ 
     var elem=selectElems[i]; 
     // If we just use elem here, its value will be what it was assigned last 
     // in the loop. That is because the handler won't be called until 
     // this loop has finished. However, by calling another function, 
     // a new scope is created with the value that we're passing into it 
     elem.onchange = createOnChangeHandler(elem); 
} 

변수이 동결도 Function.bind을 사용하여 수행하지만, 될 수있는 새로운 브라우저에서이 유일한 작품; 그러나 위 링크는이를 지원하지 않는 브라우저에서 작동하게하는 방법을 보여줍니다. http://jsfiddle.net/mendesjuan/aRMpt/143/

function loaded(){ 
    var selectElems=document.getElementsByName("select"); 
    for(i=0;i<selectElems.length;i++){ 
     var elem = selectElems[i]; 
     elem.onchange = (function (el) { 
     alert("Select index: " + el.selectedIndex) 
     }).bind(null, el); 
} 
+0

모든 JS 개발자는 이전에이 문제를 해결했다고 생각합니다. 나는 당신이 미래에 그것을 필요로 할 수도 있기 때문에 두 번째 해결책을 이해할 수 있도록 할 것이다. (만약 당신이'i' 변수를 사용하기를 원한다면). 그러나이 경우 첫 번째 것을 사용합니다. –

+0

솔직히 말해서, 저는 자바 스크립트에 초보자입니다. 특히 두 번째 예제는 이해하기가 약간 어렵습니다. 이제는 주위를 둘러 봅니다.이 예제에 대한 좋은 자습서를 알고 있다면, 저를 가리킬 수 있습니다. –

+0

일부 추가됨 어떻게 작동하는지에 대한 의견. 자유롭게 질문하고 걱정하지 마세요. 소화하는 데 약간의 시간이 걸리지 만, 이해하기 전까지는 자신을 훌륭한 JS 개발자라고 부를 수는 없습니다. –

관련 문제