2009-11-17 1 views
1

Я пытаюсь динамически изменять событие OnClick такой элемент и у меня есть что-то вроде следующего:Динамически Изменить HTML DOM событие

for (var i = 1; i < 5; i++) 
{ 
    getElementById('element' + i).onclick = function() { existingFunction(i); return false; }; 
} 

Все, кажется, работает хорошо, кроме того факта, что аргумент передается «existingFunction () 'является конечным значением i = 4 каждый раз, когда он вызывается. Есть ли способ привязать функцию к onclick, которая использует значение i во время привязки, в отличие от того, что, по-видимому, делает в данный момент, и ссылается на исходный i в for-loop.

Также существует ли способ выполнения одного и того же связывания без необходимости создавать анонимные функции каждый раз? так что я могу напрямую ссылаться на «existingFunction» в каждом onclick по соображениям производительности?

Приветствия ребята, Yong

+0

Возможные дубликаты: http://stackoverflow.com/questions/1734749/ http://stackoverflow.com/questions/643542/ http://stackoverflow.com/questions/1582634/ HTTP: //stackoverflow.com/questions/1331769/ http://stackoverflow.com/questions/1552941/ http://stackoverflow.com/questions/750486/ http://stackoverflow.com/questions/ 933343/ http://stackoverflow.com/questions/1579978/ http://stackoverflow.com/que stions/1413916/ – CMS

ответ

4

Изменить

for (var i = 1; i < 5; i++) 
{ 
    getElementById('element' + i).onclick = function() { existingFunction(i); return false; }; 
} 

в

for (var i = 1; i < 5; i++) 
{ 
    getElementById('element' + i).onclick = createOneHandler(i); 
} 

function createOneHandler(number){ 
    return function() { 
     existingFunction(number); 
    } 
} 

и он должен работать нормально.

Working Demo

Хорошее объяснение дается здесь

JavaScript, time to grok closures

+0

Ха-ха, страница, на которую вы ссылались, почти такая же ситуация. Я прочитал статью, и это было очень полезно благодаря этому. – yogibear

1

код, который вы должны работать отвечал, как вы задумали, вашу проблему с я = 4 находится в другом месте. редактирование: это неправильно, rageZ прав насчет проблемы определения области.

повторно другой вопрос: все, что вы можете сделать, это разгрузить многословие с

var f = function (i) { return function() { existingFunction(i); return false; } } 
for (...) { document.getElementById(...).onclick = f(i); } 

Кстати, вы должны использовать что-то вроде JQuery для манипулирования DOM (краткий синтаксис), и, возможно, Zeta (http://codex.sigpipe.cz/zeta/) для функции состав

var f = compose(false_, existingFunction); 
for (...) { $(...).click(f(i)); 
1

для i будучи всегда 4, у вас есть проблемы рамочный, я советую прочитать this. Scoping is действительно важно концепция, поэтому вам лучше понять, что происходит.

лучший код будет

for (var i = 1; i < 5; i++) 
{ 
    getElementById('element' + i).onclick = existingFunction; 
} 

OnClick будет проходить событие имеет аргумент, так что вы можете знать, какой элемент был щелкнул т.е.

function existingFunction(event){ 
    // DO something here 
} 

вы можете прочитать больше о событиях there. IE имеет ту же самую модель событий, что и другой браузер, поэтому вам придется ее обрабатывать.

Последний бит, я советую вам использовать рамки JS (Jquery, ExtJS, Dojo, Prototype ...), потому что это позволит упростить вашу задачу

0

Ура! Это снова замыкает петлю!См. 422784, 643542, 1552941 и др. Для обсуждения.

Есть ли способ выполнения одного и того же связывания без необходимости создавать анонимные функции каждый раз?

Да, в ECMAScript Fifth Edition, вы получаете function.bind:

for (var i = 1; i < 5; i++) 
    document.getElementById('element'+i).onclick= existingFunction.bind(window, i); 

В то же время, поскольку браузеры не поддерживают вообще его можно обезьяний залатать альтернативную реализацию bind (см the bottom of this comment для одного такой), построенный из анонимных функций как резерв.

В качестве альтернативы, назначьте одну и ту же функцию обработчика событий каждому элементу и просто посмотрите на this.id, чтобы узнать, какой номер элемента он есть.