Javascript-динамически назначать событие onclick в цикле
У меня очень простая html-страница с кодом js:
<html>
<head>
<title></title>
</head>
<body>
<div id="divButtons">
</div>
<script type="text/javascript">
var arrOptions = new Array();
for (var i = 0; i < 10; i++) {
arrOptions[i] = "option" + i;
}
for (var i = 0; i < arrOptions.length; i++) {
var btnShow = document.createElement("input");
btnShow.setAttribute("type", "button");
btnShow.value = "Show Me Option";
var optionPar = arrOptions[i];
btnShow.onclick = function() {
showParam(optionPar);
}
document.getElementById('divButtons').appendChild(btnShow);
}
function showParam(value) {
alert(value);
}
</script>
</body>
</html>
эта страница связывает 10 кнопок, но при нажатии на любую кнопку всегда отображается предупреждение "option9". Как можно назначить событие onclick, чтобы показать соответствующую опцию !?
спасибо!
7 ответов
вам придется сделать что-то вроде этого:
btnShow.onclick = (function(opt) {
return function() {
showParam(opt);
};
})(arrOptions[i]);
рассмотрим тот факт, что при выполнении функции onclick() все, что у нее есть:
showParam(optionPar);
дословно. OptionPar будет разрешен во время выполнения события click, и на данный момент это, скорее всего, последнее значение, которое вы ему присвоили. Обычно следует избегать передачи переменных таким образом.
проблема, которую вы пытаетесь решить, лучше всего решить, переписав кусок, такой как:
btnShow.value = "Show Me Option";
var optionPar = arrOptions[i];
btnShow.optionPar = optionPar;
btnShow.onclick = function(e) {
// if I'm not mistaking on how to reference the source of the event.
// and if it would work in all the browsers. But that's the idea.
showParam(e.source.optionPar);
}
прикрепить обработчик событий:
window.onload = function() {
var folderElement;
tagFolders = document.getElementById("folders");
for (i = 0; i < folders.length; i++) {
folderElement = folderButtons[i];
folderElement = document.createElement("button");
folderElement.setAttribute("id", folders[i]);
folderElement.setAttribute("type", "button");
folderElement.innerHTML = folders[i];
if (typeof window.addEventListener !== "undefined") {
folderElement.addEventListener("click", getFolderElement, false);
} else {
folderElement.attachEvent("onclick", getFolderElement);
}
tagFolders.appendChild(folderElement);
}
который может получить что-либо из элемента, который вызвал событие:
// This function is the event handler for the folder buttons.
function getFolderElement(event) {
var eventElement = event.currentTarget;
updateFolderContent(eventElement.id);
}
в этом случае вы должны встроить опцию внутри элемента / тега. В моем случае я использую id.
для jquery проверьте добавление данных событий С API:
...
for (var i = 0; i < arrOptions.length; i++) {
$('<input id="btn" type="button" value="Show Me Option"><input>').appendTo("#divButtons")
$('#btn').bind("click", {
iCount: i},
function(event) {
showParam(arrOptions[iCount]);
});
}
принятый ответ, похоже, работает, но кажется запутанным и несколько громоздким способом сделать это. Возможно, лучшим способом может быть использование атрибута data для элемента, которому вы хотите назначить прослушиватель событий. Это просто, легко понять и намного меньше кода. Вот пример:
btnShow.data = arrOptions[i];
btnShow.onclick = function() {
showParam(this.data);
}
принятый ответ правильный, но я чувствую, что никакого реального объяснения было сделано.
позвольте мне попытаться объяснить, проблема здесь в классическом недостающем закрытии.
переменная "i" увеличивается на 1 за итерацию цикла, и событие on-click фактически не выполняется, применяется ли только к элементу a, он получает суммировать до длины arrOptions, которая равна 10.
Итак, цикл продолжается до тех пор, пока " i " не будет 10, Затем, всякий раз, когда запускается событие on-click, оно принимает значение i, которое равно 10.
теперь, для решения, в решении мы используем закрытие, так что, когда мы применяем значение " i " к событию on-click элемента a, он фактически получает точное значение i во времени.
внутренняя функция события onclick создает закрытие, где она ссылается на параметр (arrOptions[i]), что означает, что фактическая переменная i находится в нужное время.
в функция в конечном итоге закрывается с этим значением безопасно, и может затем вернуть соответствующее значение при выполнении события on-click.
вы передаете только ссылку переменной на функцию, а не ее значение. Поэтому каждый раз, когда цикл повторяется, он присваивает ссылку на анонимную функцию и все они указывают на одно и то же значение в памяти. Но поскольку вы используете одно и то же имя переменной в цикле, вы перезаписываете значение переменной. Вы можете объединить переменную в строку, чтобы сохранить ее значение. Например, вот так:
btnShow.onclick = new Function("", "showParam(" + arrOptions[i] + ");");
первый параметр-это имя функции, но afaik это является необязательным (его можно оставить пустым или вообще опустить).