Sadyrbaev
@Sadyrbaev

Как правильно прописать несколько событий onclick?

Только начинаю изучать JavaScript

Есть такой код

function Place(placename) {
document.getElementById('id5').innerHTML = placename;
}

id1.onclick = Place('Вода');
id3.onclick = Place('Берег');
id4.onclick = Place('Суша');


Я полагал что он будет работать так же как и код ниже.

id1.onclick = function() {
document.getElementById('id5').innerHTML = "Вода";
};
id3.onclick = function() {
document.getElementById('id5').innerHTML = "Берег";
};
id4.onclick = function() {
document.getElementById('id5').innerHTML = "Суша";
};


Но он не работает так.

Первый код выдает в элементе с id5 последнее значение функции Place.
Второй код передает в id5 значение только при клике на соответствующий id (именно это и нужно).
Не понимаю почему первый код не работает как и второй.

Во втором коде функции объявлены, но вызываются только при событии oncklick, а в первом функция объявлена, но вызывается подряд даже без срабатывания onclick, почему?

И соответственно еще вопрос, как правильно реализуется такая простая задумка, т.е. существует некое количество объектов (например 200), при клике на любой из которых вызывается одна функция с разными параметрами соответствующими событию onclick каждого объекта?
  • Вопрос задан
  • 442 просмотра
Решения вопроса 1
sergiks
@sergiks Куратор тега JavaScript
♬♬
почему первый код не работает как и второй

onclick'у надо присваивать значением – функцию. Например id1.onclick = function() { Place('Вода'); }; Тогда эта присвоенная функция выполнится при клике.

как правильно реализуется такая простая задумка

Где собираетесь хранить параметры каждого из 200 «объектов»? Можно прямо в разметке, в data-атрибутах, как посоветовали. Но неужели будете все 200 объектов прописывать вручную? Наверняка захочется их и создавать программно. Данные отдельно, оформление отдельно. Например:
const objects = ["вода", "вода", "суша", "берег"];
function commonClickHandler(title, id) {
  console.log('Кликнули объект «%s» с id=%s', title, id);
}

objects.forEach((title, i) => {
  const div = document.createElement('div');
  const id = `id${i}`;
  div.id = id;
  div.addEventListener('click', () => commonClickHandler(title, id));
  document.body.appendChild(div);
});

Фиддл
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
dollar
@dollar
Делай добро и бросай его в воду.
Для начала, лучше использовать addEventListener().

Ну а так, смотрите, здесь:
id1.onclick = Place('Вода');
вы присваиваете в onclick результат функции Place().
Так как функция ничего не возвращает (а только производит действия), то получается так:
Place('Вода');
id1.onclick = undefined;

Чтобы функция стала обработчиком, нужно присвоить её саму, а не результат её вызова:
id1.onclick = Place;
Но так, конечно, тоже работать не будет. Теперь нужно прочувствовать этот момент, разобраться до полного понимания, чтобы двигаться дальше.
Ответ написан
Комментировать
sinneren
@sinneren
когда вы задаёте во 2 варианте - вы задаёте функцию, которая вызовется при событии onclick. На данный момент это ссылка на функцию, она не выполняется до onclick.
когда же вы задаётся в 1 варианте - вы эту функцию вызываете сразу. Потому при 3 записи всегда будет последнее значение вызова.
То есть 1 всё равно что 2 записать вот так:
id1.onclick = function() {
document.getElementById('id5').innerHTML = "Вода";
}();
id3.onclick = function() {
document.getElementById('id5').innerHTML = "Берег";
}();
id4.onclick = function() {
document.getElementById('id5').innerHTML = "Суша";
}();

Это ответ на вопрос "почему".
Теперь на ответ "как":
Выше уже сказали - делать правильно через addEventListener:
Что-то типа того:
function clickHandler (event) {
var list = { id1: 'Вода', id4: 'Суша', id3: 'Берег' };
var id = event.currentTarget.id;
document.getElementById(id).innerHTML = list[id];
}

id1.onclick = clickHandler;
id3.onclick = clickHandler;
id4.onclick = clickHandler;


И о том, как для множества:
у вас есть замечательная возможность перебирать нужные элементы в списке. Ищем по необходимым параметрам через querySelectorAll, дале перебираем одним из методов перебора, например forEach, и аналогично под каждый подставляете. Возможно список значений большой и заранее не составить, нам неизвестно какова ваша реальная задача и все условия. Предполагаю, значения и id можно вывести у элементов в data-атрибутах и оттуда брать их, нередко это так и делается.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

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