@cocomuffin

Как правильно задать событие для элемента, сгенерированного программно?

Доброго времени суток!
Подскажите, пожалуйста, как правильно навесить событие на программно генерируемый элемент?
Дано:

1. Данные в виде объекта
const mydata = {
	id: 1,
	text: 'Hello, world',
  authorName: 'Bob',
  authorID: 25
}

const mydata2 = {
	id: 2,
  text: 'Hello, Bob',
  authorName: 'Mike',
  authorID: 54
}

2. Функция-конструктор, в которой реализован метод рендера скормленных ей данных
function Component (data) {
	this.id = data.id,
  this.data = data,
  this.render = renderData(data)
}

const renderData = (data) => {
	$('#main').append(`<div class="sms" id="${data.id}">
  			<div class="avatar">
    				<img src="#" onclick="">
    				<span class="name" onclick="">${data.authorName}</span>
  			</div>
  		        <div class="message">${data.text}</div>
		</div>`);
}

3. Функции, которые должны выполняться по клику на определенные DOM-элементы
const showUserData = () => {
	console.log(this);
  console.log(`Имя "${this.data.autorName}" было нажато`);
}

const showUserAvatar = () => {
	console.log(this);
  console.log(`Аватар "${this.data.authorName}" был нажат`);
}


4. Код, который создает из данных новые компоненты и рендерит их на странице, а так же собирает все компоненты в один массив:
(function() {
  const component1 = new Component(mydata);
  const component2 = new Component(mydata2);
  const arrayOfAllComponents = [];
  arrayOfAllComponents.push(component1, component2);
})();


Вопрос в том, как правильно навесить на элементы img и span.name событие onclick, коллбэком для которого будет функция showUserAvatar для img и функция showUserData для span не с помощью
$('img').on('click', function() {...})
где-нибудь в конце кода, а динамически, в момент, когда элемент рендерится - чтобы у функции был свой контекст, соответствующий текущему элементу - в случае, если мы просто навешиваем одинаковые события на все отрисованные смс-ки, мы можем сделать это только один раз.

Т.е. страничка отрисовывается, и тут с сервера приходит еще один объект, из которого мне надо создать новый компонент и навесить на него те же события (клик на аватарку и клик на имя пользователя).

По идее, необходимо искать, какому элементу массива (т.е. какому компоненту) соответствует запись, по которой кликнули, и уже вызывать методы в нужном контексте нужного объекта... Но не могу сообразить, как это сделать.

Ссылка на JSFiddle
  • Вопрос задан
  • 39 просмотров
Решения вопроса 1
Kozack
@Kozack Куратор тега JavaScript
Thinking about a11y
$(`<div class="sms" id="${data.id}">
  			<div class="avatar">
    				<img src="#" onclick="">
    				<span class="name" onclick="">${data.authorName}</span>
  			</div>
  		        <div class="message">${data.text}</div>
    </div>`).appendTo(#main).on(...)
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
Robur
@Robur
Знаю больше чем это необходимо
Используйте event delegation. Один раз вешаете обработчик и создавайте элементы сколько хотите.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы