2012-05-29 4 views
0

Я хочу сгенерировать некоторые <select элементов динамически. Я копирую существующий и меняю имя и событие onchange. Вот где моя проблема: у каждого <select> есть свой идентификатор. Когда срабатывает onChange-Event, он должен отвечать на Value и ID элемента. Я не знаю, как точно определить JavaScript Closure. Я попробовал его с «this.value», но, видимо, это не работает ... Я уже нашел this пример, но он не работает для меня вообще:/Динамически сгенерированные элементы выбора и закрытие JavaScript

В JavaScript:

var i = 0; 
var selectArray = []; 

function addSelector(){ 

var container = document.getElementById("check0"); 

selectArray[i] = document.getElementsByName("select0")[0].cloneNode(true); 
selectArray[i].name = 'select'+i; 
selectArray[i].onchange = function(v, i) { 
     return function() { 
      changeType(v, i) 
     } 
    }(this.value, i); 

container.appendChild(selectArray[i]); 
} 

function changeType(selected, i) { 
    switch (selected) { 
     case 'One': 
      alert(selected+' , '+i); 
      break; 
     case 'Two': 
      alert(selected+' , '+i); 
      break;   
     case 'Three': 
      alert(selected+' , '+i); 
      break; 
     case 'Four': 
      alert(selected+' , '+i); 
      break; 
     case 'Five': 
      alert(selected+' , '+i); 
      break; 
    } 
} 

(я пытался опубликовать HTML Aswell, но по какой-то причине я не был в состоянии сделать это;))

Here is the fiddle

+0

Значение 'i' никогда не меняется –

ответ

1

this.value не известно здесь:

function addSelector(){ 
    /* ... */ 
    selectArray[i].onchange = (function(v, i) { 
     return function() { 
      changeType(v, i) 
     } 
    })(this.value, i); 
    /* ... */ 
} 

this будет undefined (в строгом режиме) или window (нормальный режим). Как должен знать JavaScript, что this является ссылкой на созданный/клонированный объект <select>? this будет правильно внутри вашего onchange, так что вы не должны включать в себя это путем закрытия, только индекс i должен быть включен:

selectArray[i].onchange = (function(index) { 
    return function() { 
     changeType(this.value, index) 
    } 
})(i); 

Обратите внимание, что ваш синтаксис для предупреждения неправильно - вы должны использовать alert(selected + " " + i) вместо этого, поскольку второй аргумент будет проигнорирован.

Смотрите также:

+0

Спасибо, вот что мне нужно знать! Я не был уверен, как сказать changeType «принять значение динамически созданного селектора». Вот почему я думал, что должен установить «this.value» также как параметр ... Теперь он работает так, как я хотел. – cvoigt

1

Ваш пример очень трудно следовать. Есть целый ряд проблем с этим

  • i никогда не меняется
  • this.value не имеет правильное значение, когда вы называете его, но это легко выяснить из обработчика

следующий скрипт делает то, что я думаю, что вам нужно http://jsfiddle.net/FNFQU/13/

function addHandler(node, index){ 
    node.onchange = function() { 
     alert('Changed select index ' + index + '. Its value is ' + node.value); 
    } 
} 

function duplicateSelectElement() { 
    var container = document.getElementById("check0"); 
    var allSelects = document.getElementsByName("select"); 
    var firstSelect = allSelects[0]; 
    var newSelect = firstSelect.cloneNode(true); 
    addHandler(newSelect, allSelects.length + 1); 
    container.appendChild(newSelect); 
} 

addHandler(document.getElementById('select0'), 1); 

document.getElementById('btn').onclick = duplicateSelectElement; 

Используя следующий HTML

<input type="button" 
     id="btn" 
     value="Add Selector!" /> 
<div id="check0"> 
<select id="select0" name="select"> 
    <option selected>One</option> 
    <option>Two</option> 
    <option>Three</option> 
    <option>Four</option> 
    <option>Five</option> 
</select> 
</div>​ 
+0

Спасибо за ваши усилия. Действительно, я никогда не меняюсь - я забыл увеличить его. Ваш скрипт делает то, что я хотел, но мне нужно сделать это с помощью закрытий. Вот почему я задал другой ответ как правильный. Благодарим за быстрый ответ! – cvoigt

+0

@vogti Ответ, который поможет вам найти вашу проблему, заслуживает повышения. В моем ответе используется закрытие, оно не использует анонимную функцию самозапуска. Зачем вам нужна * анонимная функция самозапуска? –

+0

В вашем ответе может быть закрытие, но другой ответ помог мне точно решить мою проблему. Спасибо много снова, я дал вам! – cvoigt