Обращение к динамически созданным элементам.
Здравствуйте.
Через addEventListener вызываю событие mouseover и выполняю функцию, которая создает новый элемент var el = document.createElement("div"); el.id = "ele"; Теперь мне нужно вызвать событие клик через addEventListener на этом элементе. Если данное событие вызвать в функции после создания элемента, то все работает, если же извне (отдельно), то не работает, т.к. видимо элемента не существует. Соответственно, вопрос, как вызвать событие к еще несуществующим элементам? |
el.addEventListener("click", function( e ) {
alert( e.target ); // ссылка на наш элемент
}, false);
|
Дело в том, что событие клик не сработает, т.к. видимо el еще нет. Нужно чтобы выполнялась функция при событие click на el. Который еще не создан.
|
Цитата:
|
el. еще не создан. Но инструкция уже есть. есть скажем в div 10 span. Я создаю одинадцатый. Вот на этот одинадцатый инструкция не распростроняется, а нужно чтобы распростронялось. В джиквери для этогго есть функция live к примеру.
|
ну если вещать обработчик на родителя, то ему по барабану сколько там у него детей
|
Обращение идет через querySelectorAll("#id .class"). Хотя вопрос больше как сделать так, чтобы обращаться можно было ко всем элементам, не зависимо были они ранее созданы на странице или нет.
|
через e.target по признаку (классу, id и т.п.)
либо получать нужные элементы каждый раз при вызове обработчика, а не один раз |
Спасибо. А можно примеры с обоими вариантами, а то я что-то не соображу. Т.е. как мне вызвать их указав ("#id .class")
|
тестовый пример с возможностью запуска [html run]
|
[html run] - это я так понимаю чтобы введенный код в сообщении по нажатию на кнопку срабатывал. Подскажите, как это делается?
|
|
<!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>
|
<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>
|
Спасибо за ответ. Но дело в том, что мне нужно передать элемент в объект, просто для того, чтобы использовать другие методы данного объекта. Кроме прочего это уже используется в очень многих местах. Поэтому, чтобы не переписывать алгоритм, мне бы желательно как-то получить все доступные элеменеты, через метод topmenu.Sattr("#idd .cl") обращаясь к ним тем же способом, что и querySelectorAll. Можно как-то так сделать, в принципе также, как сделано в джиквери в функции Like
|
предполагаю: нужно использовать MutationEvents
https://developer.mozilla.org/en-US/...lug=DOM_Events http://habrahabr.ru/post/114244/ иначе живости не получить, ну либо при добавке нового элемента вещать обработчик на него |
Большое спасибо. Возможно, это действительно то, что нужно. Я так понял что MutationEvents отслеживает изменения дом элементов. Но никакой дельной информации - описания по данному поводу не нашел. Ваших ссылок к сожалению оказалось недостаточно, не говоря уже о не знании английского языка. Может кто-нибудь подскажет расширенную информацию по данному вопросу. Также интересует кроссбраузерность и поддрержка хотя бы ie8
|
В общем, сколько не искал, так и не нашел никакой достаточно подробной информации по MutationEvents. Хотя насколько понял, это относится к дом3 и видимо довольно плохо поддерживается. Может кто-нибудь все-таки подскажет, как можно решить мою проблему с MutationEvents или без.
|
не лучший вариант, но можно сделать что-нибудь типа такого
<!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>
|
Спасибо. Попробую. Хотелось правда расширить сам методо sob и/или Sattr, чтобы сделать события живыми. Надо было сразу подумать об этом, я не знал, что не будет с вновь созданными событиями работать.
|
Спасибо, сделал через targer, хотя на будущее надо бы добавить еще метод, который получит все элементы по тому же принципу, что и сейчас, но и в том числе даже если они еще не созданы на странице. Т.е. что-то навроде функции Live, т.ч. буду признателен каждому, кто добавить какой-нибудь дельной информации по данному вопросу.
|
Возник еще один вопрос, как удалить созданный элемент правильно.
Пишу так.
.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 Как правильно определить когда нужно этот элемент удалить? Надеюсь, поможете. |
ну он же вычисляет значения в условии, а id не всегда есть
|
Так а как бы это правильно записать. Если например нет id. Или еще лучше, если мышь выходит за пределы #idd
|
<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>
|
Спасибо, попробую
|
<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 ? |
sotik,
window.onload = fucntion () { document.getElementsByName("sost")[0].value = val; }
|
Спасибо.А я тем временем нашел еще одно решение:
//функция смены кнопки function press(f) { if(f.but.value == "Смотреть бой"){f.but.value = "Отменить просмотр";} } |
с кнопками можно делать:
• изменять надпись на кнопке; • указывать обработчик события, который будет выполняться при нажатии на кнопку; • выдавать кнопке определенный обработчик в зависимости от внешних условий. Интересует третий пункт. Если на кнопку было повешано onClick="press(this.form)", то как это можно изменить на onClick="Ring(this.form)" ? желательно с примением моей функции (//функция смены кнопки). |
//функция смены кнопки
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> По нажатию на кнопку интервал запускается, но потом по нажатию ээтой же кнопки уже не останавливается. Почему и как это исправить? Подсобите пожалуйста |
понял ошибку, которую уже однажды сделал.
не надо объявлять переменную: var interval нужно просто interval |
sotik, http://javascript.ru/formatting (уже второй раз)
|
А вот эта штуковина что-то не работает,может где синтаксис не верный?
var val = ["Смотреть бой", "Отменить просмотр"];
window.onload = fucntion () { document.getElementsByName("but")[0].value = val[0]; }
<form>
<input type="button" name="but" value="" onClick="press(this.form)" />
</form>
|
sotik, игнорируешь?
|
да не, не игнорирую,просто не пойму в чем дело.. :)
|
смысл в оформлении приводимого кода, пройдя по ссылке, можно посмотреть как это делается
|
| Часовой пояс GMT +3, время: 13:06. |