Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Обращение к динамически созданным элементам. (https://javascript.ru/forum/dom-window/31942-obrashhenie-k-dinamicheski-sozdannym-ehlementam.html)

platedz 27.09.2012 01:12

Обращение к динамически созданным элементам.
 
Здравствуйте.
Через addEventListener вызываю событие mouseover и выполняю функцию, которая создает новый элемент
var el = document.createElement("div");
el.id = "ele";
Теперь мне нужно вызвать событие клик через addEventListener на этом элементе. Если данное событие вызвать в функции после создания элемента, то все работает, если же извне (отдельно), то не работает, т.к. видимо элемента не существует.
Соответственно, вопрос, как вызвать событие к еще несуществующим элементам?

devote 27.09.2012 02:07

el.addEventListener("click", function( e ) {
    alert( e.target ); // ссылка на наш элемент
}, false);

platedz 27.09.2012 02:47

Дело в том, что событие клик не сработает, т.к. видимо el еще нет. Нужно чтобы выполнялась функция при событие click на el. Который еще не создан.

bes 27.09.2012 10:33

Цитата:

Сообщение от platedz
Нужно чтобы выполнялась функция при событие click на el. Который еще не создан.

аналогия: дитя ещё не зачали, но оно уже чего-то делает

platedz 27.09.2012 13:40

el. еще не создан. Но инструкция уже есть. есть скажем в div 10 span. Я создаю одинадцатый. Вот на этот одинадцатый инструкция не распростроняется, а нужно чтобы распростронялось. В джиквери для этогго есть функция live к примеру.

bes 27.09.2012 13:45

ну если вещать обработчик на родителя, то ему по барабану сколько там у него детей

platedz 27.09.2012 14:11

Обращение идет через querySelectorAll("#id .class"). Хотя вопрос больше как сделать так, чтобы обращаться можно было ко всем элементам, не зависимо были они ранее созданы на странице или нет.

bes 27.09.2012 14:18

через e.target по признаку (классу, id и т.п.)
либо получать нужные элементы каждый раз при вызове обработчика, а не один раз

platedz 27.09.2012 14:49

Спасибо. А можно примеры с обоими вариантами, а то я что-то не соображу. Т.е. как мне вызвать их указав ("#id .class")

bes 27.09.2012 17:16

тестовый пример с возможностью запуска [html run]

platedz 27.09.2012 21:41

[html run] - это я так понимаю чтобы введенный код в сообщении по нажатию на кнопку срабатывал. Подскажите, как это делается?

bes 27.09.2012 22:02

http://javascript.ru/formatting

platedz 28.09.2012 01:22

<!DOCTYPE >
<HTML>
<style>
.cl {width:100px; height: 40px; border: 1px solid red;}
#di {border: 1px solid blue;}
</style>

<BODY>
<div id="idd">
<div class="cl">1</div>
<div class="cl">2</div>
<div>
<script>
topmenu = (function(window) {
var elements = {};

return {
			Sattr: function(name)
				{
				try{ elements = document.querySelectorAll(name); }catch(e){}
					
					return this;
				},

			sob: function(type,block) 
				{
				
					
					for(var i=0; i<elements.length;i++)
						{
							try { 
									try {

										elements[i].addEventListener(type, block, false);

									} catch(e) {

										elements[i].attachEvent("on"+type, block);

									}
								} catch(e){}
						}
					return this;

				}
				}}());
topmenu.Sattr("#idd .cl").sob("click",function(){ 
if(!document.getElementById("di")) {
						var div = document.createElement("div");
							div.id = "di";
							div.innerHTML = "div";
							} else var div = document.getElementById("di");
							this.appendChild(div);
							
});
					var dv = document.createElement("div");
							dv.className = "cl";
							dv.innerHTML = "3";
							document.getElementById("idd").appendChild(dv);
</script>
</BODY>
</HTML>

bes 28.09.2012 10:37

<style>
.cl {width:100px; height: 40px; border: 1px solid red;}
#di {border: 1px solid blue;}
</style>

<div id="idd">
	<button>add</button>
	<div class="cl">1</div>
	<div class="cl">2</div>
<div>

<script>
window.onload = function () {
	document.getElementById('idd').onclick = function (e) {
		e = e || event;
		var target = e.target || e.srcElement;
		if (target == this.children[0]) {
			var el = document.createElement('div');
			el.innerHTML = this.children.length - 1;
			el.className = 'cl';
			this.appendChild(el);
		} else 
		if (target.className == 'cl') {
			if(!document.getElementById("di")) {
				var el = document.createElement("div");
				el.id = "di";
				el.innerHTML = "div";
			} else {
				var el = document.getElementById("di");
			}
			target.appendChild(el);
		}
	}
}
</script>

platedz 28.09.2012 12:06

Спасибо за ответ. Но дело в том, что мне нужно передать элемент в объект, просто для того, чтобы использовать другие методы данного объекта. Кроме прочего это уже используется в очень многих местах. Поэтому, чтобы не переписывать алгоритм, мне бы желательно как-то получить все доступные элеменеты, через метод topmenu.Sattr("#idd .cl") обращаясь к ним тем же способом, что и querySelectorAll. Можно как-то так сделать, в принципе также, как сделано в джиквери в функции Like

bes 28.09.2012 13:47

предполагаю: нужно использовать MutationEvents
https://developer.mozilla.org/en-US/...lug=DOM_Events
http://habrahabr.ru/post/114244/
иначе живости не получить,
ну либо при добавке нового элемента вещать обработчик на него

platedz 28.09.2012 16:14

Большое спасибо. Возможно, это действительно то, что нужно. Я так понял что MutationEvents отслеживает изменения дом элементов. Но никакой дельной информации - описания по данному поводу не нашел. Ваших ссылок к сожалению оказалось недостаточно, не говоря уже о не знании английского языка. Может кто-нибудь подскажет расширенную информацию по данному вопросу. Также интересует кроссбраузерность и поддрержка хотя бы ie8

platedz 29.09.2012 03:47

В общем, сколько не искал, так и не нашел никакой достаточно подробной информации по MutationEvents. Хотя насколько понял, это относится к дом3 и видимо довольно плохо поддерживается. Может кто-нибудь все-таки подскажет, как можно решить мою проблему с MutationEvents или без.

bes 29.09.2012 14:16

не лучший вариант, но можно сделать что-нибудь типа такого
<!DOCTYPE >
<HTML>
<style>
.cl {width:100px; height: 40px; border: 1px solid red;}
#di {border: 1px solid blue;}
</style>

<BODY>
<div id="idd">
<div class="cl">1</div>
<div class="cl">2</div>
<div>
<script>
topmenu = (function(window) {
var elements = {};

return {
			Sattr: function(name)
				{
				try{ elements = document.querySelectorAll(name); }catch(e){}
					
					return this;
				},

			sob: function(type,block) 
				{
				
					
					for(var i=0; i<elements.length;i++)
						{
							try { 
									try {

										elements[i].addEventListener(type, block, false);

									} catch(e) {

										elements[i].attachEvent("on"+type, block);

									}
								} catch(e){}
						}
					return this;

				}
				}}());

document.body.onmousedown = function (){
topmenu.Sattr("#idd .cl").sob("click",function(){ 
if(!document.getElementById("di")) {
						var div = document.createElement("div");
							div.id = "di";
							div.innerHTML = "div";
							} else var div = document.getElementById("di");
							this.appendChild(div);
							
});
}
					var dv = document.createElement("div");
							dv.className = "cl";
							dv.innerHTML = "3";
							document.getElementById("idd").appendChild(dv);
							



</script>
</BODY>
</HTML>

platedz 29.09.2012 17:52

Спасибо. Попробую. Хотелось правда расширить сам методо sob и/или Sattr, чтобы сделать события живыми. Надо было сразу подумать об этом, я не знал, что не будет с вновь созданными событиями работать.

platedz 03.10.2012 01:46

Спасибо, сделал через targer, хотя на будущее надо бы добавить еще метод, который получит все элементы по тому же принципу, что и сейчас, но и в том числе даже если они еще не созданы на странице. Т.е. что-то навроде функции Live, т.ч. буду признателен каждому, кто добавить какой-нибудь дельной информации по данному вопросу.

platedz 03.10.2012 13:09

Возник еще один вопрос, как удалить созданный элемент правильно.

Пишу так.

.sob("mouseout",function(e)
     {
      	if(event.relatedTarget.id != "null" && event.relatedTarget.id != "undefined" &&    event.relatedTarget.id != "di" && event.relatedTarget.parentNode.id != "di" && document.getElementById("di")) {

	document.getElementById("di").parentNode.removeChild(document.getElementById("di"));
	
	}
		
	});


В общем и целом все работает, но отладчик выдает ошибки

Uncaught TypeError: Cannot read property 'id' of null

Как правильно определить когда нужно этот элемент удалить? Надеюсь, поможете.

bes 03.10.2012 13:18

ну он же вычисляет значения в условии, а id не всегда есть

platedz 03.10.2012 13:38

Так а как бы это правильно записать. Если например нет id. Или еще лучше, если мышь выходит за пределы #idd

bes 03.10.2012 14:01

<div style="background: gray">div</div>
<script>
document.body.children[0].onmouseover = function () {
	if (!document.getElementById('di')) {
		this.insertAdjacentHTML('afterBegin', '<button id="di">click</button>');
	} 
}
document.body.children[0].onmouseout = function (e) {
	e = e || event;
	var rt = e.relatedTarget || e.toElement;
	while(rt && rt != this) {
		rt = rt.parentNode;
	}
	if (rt == this ) {
		return;
	} else if (document.getElementById('di')) {
		this.removeChild(document.getElementById('di'));
	}
}
</script>

platedz 03.10.2012 14:16

Спасибо, попробую

sotik 04.10.2012 09:02

<js>
var val = "Смотреть бой";
</js>
<div id="block_id">
<form name="boy">
<input type="button" name="sost" value="" onclick="sostform(boy)" />
</form>
</div>
Можно ли как-нибудь переменную val вставить в value без использования innerHTML ?

lord2kim 04.10.2012 09:18

sotik,
window.onload = fucntion () { document.getElementsByName("sost")[0].value = val; }

sotik 04.10.2012 09:37

Спасибо.А я тем временем нашел еще одно решение:
//функция смены кнопки
function press(f) {
if(f.but.value == "Смотреть бой"){f.but.value = "Отменить просмотр";}
}

sotik 04.10.2012 09:54

с кнопками можно делать:
• изменять надпись на кнопке;
• указывать обработчик события, который будет выполняться при нажатии на кнопку;
• выдавать кнопке определенный обработчик в зависимости от внешних условий.
Интересует третий пункт.
Если на кнопку было повешано onClick="press(this.form)",
то как это можно изменить на onClick="Ring(this.form)" ?
желательно с примением моей функции (//функция смены кнопки).

sotik 04.10.2012 10:40

//функция смены кнопки
var val = ["Смотреть бой", "Отменить просмотр"];
function press(f) {
if(f.but.value == val[0]){Ring('look');f.but.value = val[1];}
else if(f.but.value == val[1]){ clearInterval( interval );f.but.value = val[0];}
}

function Ring(ini)
{
var i = 0; //обнуляем счетчик
var interval = setInterval( //задаём интервал
    function(){
        if(++i >= 2){
clearInterval( interval );
}else{
Login(ini);}
},
 20 * 1000)
}

<div id="block_id">
<form>
<input type="button" name="but" value="Смотреть бой" onClick="press(this.form)" />
</form>
</div>

По нажатию на кнопку интервал запускается, но потом по нажатию ээтой же кнопки уже не останавливается.
Почему и как это исправить?
Подсобите пожалуйста

sotik 04.10.2012 10:46

понял ошибку, которую уже однажды сделал.
не надо объявлять переменную:
var interval
нужно просто
interval

bes 04.10.2012 10:47

sotik, http://javascript.ru/formatting (уже второй раз)

sotik 04.10.2012 11:55

А вот эта штуковина что-то не работает,может где синтаксис не верный?
var val = ["Смотреть бой", "Отменить просмотр"];
window.onload = fucntion () { document.getElementsByName("but")[0].value = val[0]; }
<form>
<input type="button" name="but" value="" onClick="press(this.form)" />
</form>

bes 04.10.2012 12:00

sotik, игнорируешь?

sotik 04.10.2012 12:08

да не, не игнорирую,просто не пойму в чем дело.. :)

bes 04.10.2012 13:04

смысл в оформлении приводимого кода, пройдя по ссылке, можно посмотреть как это делается


Часовой пояс GMT +3, время: 02:30.