Обращение к динамически созданным элементам.
Здравствуйте.
Через 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, время: 02:30. |