Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 03.10.2014, 14:19
Интересующийся
Отправить личное сообщение для devastor Посмотреть профиль Найти все сообщения от devastor
 
Регистрация: 09.09.2014
Сообщений: 27

Перезапись событий
Добрый день, друзья!
Столкнулся с проблемой:
при первом вызове функции plus(), всё срабатывает как надо - при нажатии на созданный point1 вызывается созданный див flying1, но при втором вызове события на все дивы перезаписываются и получается что при нажатии на див point1, point2 вызывается flying2, при третьем вызове point1, point2, point3 начинают ссылаться на flying3 и т.д
как сделать что бы событие onclick не перезаписывалось, при каждом вызове функции?
Код:
var i = 0;
function plus(){
	if (i > 3) return;
	i++;
	var Form = document.getElementById('plus');
	var Div = document.createElement("div");
	Div.className =  'point';
	Div.id = 'point'+i;
	Div.onclick = function (){
		$('#flying'+i).css({visibility:'visible'});
	};
	Form.appendChild(Div);
        Div.innerHTML = '<span class="icon-location2">';
	var flDiv = document.createElement("div");
	flDiv.className =  'flying';
	flDiv.id = 'flying'+i;
	Form.appendChild(flDiv);
<div id="plus"></div>
ЗЫ: где почитать, как делать компилируемый JS код на этом форуме?
Ответить с цитированием
  #2 (permalink)  
Старый 03.10.2014, 14:55
Аватар для ksa
ksa ksa вне форума
CacheVar
Отправить личное сообщение для ksa Посмотреть профиль Найти все сообщения от ksa
 
Регистрация: 19.08.2010
Сообщений: 14,118

Сообщение от devastor
как сделать что бы событие onclick не перезаписывалось, при каждом вызове функции?
Оно не перезаписывается.
Просто "этому" как раз и равняется переменная i в конце цикла...
Ответить с цитированием
  #3 (permalink)  
Старый 03.10.2014, 14:58
Аватар для ksa
ksa ksa вне форума
CacheVar
Отправить личное сообщение для ksa Посмотреть профиль Найти все сообщения от ksa
 
Регистрация: 19.08.2010
Сообщений: 14,118

Некий вариант решения...

Div.onclick = (function (N){
		return function (){
			$('#flying'+N).css({visibility:'visible'});
		};
	})(i);
Ответить с цитированием
  #4 (permalink)  
Старый 03.10.2014, 15:07
Аватар для ksa
ksa ksa вне форума
CacheVar
Отправить личное сообщение для ksa Посмотреть профиль Найти все сообщения от ksa
 
Регистрация: 19.08.2010
Сообщений: 14,118

devastor, если бы был полный тестовый пример - можно было бы придумать вариант и получше...
Ответить с цитированием
  #5 (permalink)  
Старый 04.10.2014, 19:16
Профессор
Отправить личное сообщение для kostyanet Посмотреть профиль Найти все сообщения от kostyanet
 
Регистрация: 23.10.2010
Сообщений: 2,718

Тут разрыв шаблона:

Div.id = 'point'+i;
	Div.onclick = function (){
		$('#flying'+i).css({visibility:'visible'});
	};


в id счетчик приваривается, а в функции остается референтным (то есть все кто давит эту функцию давят на последний i). Ну и глюки. Надо по id щелкать, чтоб не париться кложами (closures).

Div.onclick = some_func(this);
some_func(elem){
counter=elem.id.replace('prefix','');
//...
}
Ответить с цитированием
  #6 (permalink)  
Старый 04.10.2014, 19:44
Профессор
Отправить личное сообщение для kostyanet Посмотреть профиль Найти все сообщения от kostyanet
 
Регистрация: 23.10.2010
Сообщений: 2,718

Где-то была тем про кложи, писали что это замыкание. Замыкание это когда скрепку в розетку. На самом деле это смыкание, смычка.

Div.onclick = function (){
   $('#flying'+i).css({visibility:'visible'});
};


В атрибут onclick записалось то, что вы написали, буквально - текст. Чтобы его исполнить когда придет событие - интерпретатор должен пойти туда, где это текст написан. Следовательно все что написано вокруг этого текста - становится релевантным тому тексту, который записан в атрибуте onclick. В частности там написано что есть такая переменная с именем i, потому что она нарисована глобально. Надо ее взять, прибавить к другому тексту, найти по тому тексту адрес в памяти, по тому адресу... это другая история.

Так вот, когда интерпретатор приходит туда, где этот текст был записан - он берет то, что в этом тексте указано взять, но, к этому моменту под тем же именем в i уже другое значение, из-за событий которые произошли до того как и поменяли значение. Функций у вас 3 штуки, но все они юзают одну и ту же глобальную для них переменную i, групповуха, короче, детектед.

Чтобы юзать ее индивидуально надо написать еще одну кложу как и нарисовано в примере ksa: N это копия i которую закачали через ж-у внутрь функции с текущим на момент закачки значением i. Теперь когда интерпретатор приползет выполнять текст в атрибуте onclick он возьмет указанную N, которая такая же переменная как i, но которую не шевелят всякие там события. В итоге для 3-х функций будет 3 переменных по 1 на каждую.

ЗЫ Я подумал что будет понятнее изобразить i как window.i; Если стопицот функций обращаются к window.i и каждая меняет ее значение как хочет (например как функция plus) то хз что можно ожидать.

Последний раз редактировалось kostyanet, 04.10.2014 в 19:47.
Ответить с цитированием
  #7 (permalink)  
Старый 04.10.2014, 20:19
Профессор
Отправить личное сообщение для kostyanet Посмотреть профиль Найти все сообщения от kostyanet
 
Регистрация: 23.10.2010
Сообщений: 2,718

Да, еще как из i получается N. Это особенность js такая - что нормальному человеку без полкило водки не разобраться. Насколько я понимаю i становится this через ж-у, а N, соответственно берет значение this со рта. Я по-первости думал что все это идет через мозг Жанны Агузаровой, честно-честно.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Ползунок JQuery: несколько событий? Veterinar jQuery 9 10.01.2014 20:57
Добавление обработчика событий при добавлении элементов vladimircape Events/DOM/Window 3 13.09.2012 09:57
Переопределение событий lispik jQuery 4 13.01.2011 12:30
Скопировать обработчики событий с одного элемента на другой. Jurasmi Events/DOM/Window 3 10.11.2010 19:03
Кроссбраузерное навешивание событий на динамический элемент Pula Events/DOM/Window 5 02.07.2009 15:02