2013-04-10 3 views
0

У меня есть проблема с этим яваскриптом кода:Javascript классов и обработчики событий

function MyClass() { 
    var id_nr = Math.ceil(Math.random() * 999999); 
    this.button_id = 'button_' + id_nr; 
} 


MyClass.prototype = { 
    createButton: function() { 
     var msg = 'Button \'' + this.button_id + '\' was clicked'; 

     var my_button = (
      '<input type="button" id="' 
      + this.button_id 
      + '" value="Click Me" /\>' 
     ); 

     document.body.innerHTML += '<div>' + my_button + '</div>'; 
     document.getElementById(this.button_id).onclick = function() { alert(msg); } 
    } 
}; 


window.onload = function() { 
    var s = new MyClass(); 
    s.createButton(); 
}; 

Да, текущий код работает нормально. Но проблема возникает, когда я добавить более одного MyClass объектов:

window.onload = function() { 
    var s = new MyClass(); 
    s.createButton(); 

    var w = new MyClass(); 
    w.createButton(); 

    /* ...and many other buttons */ 

}; 

По какой-то причине OnClick событие будет срабатывать только при нажатии кнопки, которая была создана в прошлом. И я не знаю, почему.

Один из способов может быть что-то вроде этого:

<input type="button" onclick="javascript:doSomeThing();" /> 

Но, к сожалению, это не правильное решение правый ряд, потому что моя цель состоит в том, что onclik событие должно быть в состоянии назвать еще методы класса, а также. (Эти методы еще не созданы).

Как я могу сделать этот код работоспособным? Приветствуется всякая помощь.

ответ

0

Когда вы используете innerHTML, содержимое удаляется из DOM, а затем снова считывается и анализируется, прерывая любой прослушиватель событий прошлых событий, который вы, возможно, добавили.

Если вы хотите сделать это в vanilla JS, рассмотрите возможность использования appendChild() и, кроме того, я бы предложил addEventListener(). Ваш код будет выглядеть так:

var my_button = document.createElement('input'); 
my_button.type = 'button'; 
my_button.id = this.button_id; 
my_button.value = 'Click me'; 

document.body.appendChild(my_button); 
my_button.addEventListener('click', function() { alert (msg) }); 

Working example with vanilla Javascript

Если вы до использовать некоторые JQuery, это было бы намного проще осуществить. Ваш метод будет выглядеть примерно так:

var my_button = $('<input>') 
       .prop('type', 'button') 
       .prop('id', this.button_id) 
       .val('Click Me') 
       .on('click', function() { alert(msg) }); 

$('body').append(my_button) 

Working example with jQuery

Или вы могли бы, возможно, использовать метод jQuery.on() делегировать обработчик событий для всех экземпляров ваших кнопок.

Working example with delegated event handler

+0

Я уже пробовал jQuery, но такая же ошибка остается. Кроме того, идентификаторы ID не могут быть причиной здесь: каждый элемент ввода будет иметь уникальный идентификатор в этом коде. – user2266705

+0

Изменил мой ответ, я неправильно понял, как были созданы ваши идентификаторы. – Sunyatasattva

+0

Я также добавил некоторые рабочие примеры в JSBin, проверьте их! :) – Sunyatasattva

0

Использование innerHTML здесь, кажется, сломать слушатель события "OnClick".

Вы можете избежать этого с помощью метода document.createElement для создания элемента HTML:

var but = document.createElement("input"); 
but.type = "button"; 
but.id = this.button_id; 
but.value = "Click me"; 

document.body.appendChild(but); 

Personaly, я предпочитаю использовать JQuery для манипулирования элемента дерева DOM, как это предлагает действительно мощный инструмент для этого.

Смежные вопросы