Выбор нужного элемента дом дерева
Доброго времени суток, вот по чуть учу Js и столкнулся с задачей, которую не получается решить. Может вы подскажите в чем моя ошибка.
Задача: Вот так выглядит страница. В каждом вложенном диве есть еще элементы. Задача поменять местами второй и третий див. У них есть классы но нет Id. Обязательно делать именно жс и кроссбраузерно. <div id="content-wrap"> <div></div> <div></div> <div></div> </div> Вот я написал такое дело var main = document.getElementById('content-wrap') var divall = main.getElementsByTagName('div') main.appendChild(divall[1]) Логика моя: Выбрали див с ид content-wrap. Пробежались по нему и выбрали все div. Див который второй взяли и перекинули в конец родителя. При таком коде мне Лисичка пишет TypeError: main is null var divall= main.getElementsByTagName('div') |
<!DOCTYPE HTML> <html> <head> </head> <body> <div id='wrapper'> <div>1 </div> <div> 2</div> <div>3 </div> <div> 4</div> </div> <script> var wrapper_ = document.getElementById('wrapper'); var elem = wrapper_.children[1]; wrapper_.insertBefore(elem, wrapper_.children[3]) </script> </body> </html> |
Спасибо большое, как же все просто было...
|
main is null
Т.е. нет элемента с таким id. С вероятностью 100% вы запускаете скрипт раньше чем в коде появляется данный элемент. Javscript выполняется по мере загрузки, а не после.(если вы специально того не обозначите) ... <div id="content-wrap"> <div>1</div> <div>2</div> <div>3</div> </div> <script type="text/javascript"> var main = document.getElementById('content-wrap') var divall = main.getElementsByTagName('div') main.appendChild(divall[1]) </script> |
И да, решение от cyber, не будет работать если элементов 3, надо так:
var wrapper_ = document.getElementById('wrapper'); var elem = wrapper_.children[1]; wrapper_.insertBefore(elem, wrapper_.children[3] || null) //ксли вторым параметром null - работает как appeendChild, а если undefined - кидает ошибку |
А вот у меня возник еще один вопрос, задача стояла куда более обширно нежели тут описал в итоге поучил вот такой код
<script> var wrapper_ = document.getElementById('content-wrap'); var elem = wrapper_.children[4]; var after_main = wrapper_.children[2]; after_main.style.width = "900px"; var after_main_stage1 = after_main.children[0]; var after_main_stage2 = after_main.children[1]; after_main_stage1.style.cssText = "float:left;\ "; after_main_stage1.rule.style.cssText = "float:left;\ "; after_main_stage2.style.cssText = "float:left;\ "; var after_main_stage3 = after_main_stage2.children[1]; after_main_stage3.style.cssText = "float:left;\ width:300px;\ " ; wrapper_.insertBefore(elem, wrapper_.children[2]) wrapper_.children[2].style.width = "940px"; var cat_ch3 = elem.children[0]; var cat_ch4 = cat_ch3.children[1]; var light = elem.children[1]; var light2 = elem.children[2]; cat_ch4.parentNode.insertBefore(light2, cat_ch4.nextSibling); cat_ch4.parentNode.insertBefore(light, cat_ch4.nextSibling); elem.children[0].style.cssText = "position:relative ; \ "; light.style.cssText="position:absolute;\ bottom:45px; \ "; light2.style.cssText="position:absolute;\ bottom:25px; \ "; var float_l = document.getElementsByTagName('td'); var text_float = float_l[0]; var text_float_stage1 = text_float.children[0]; var dd_st = text_float_stage1.getElementsByTagName('dd'); for (var i=0; i < dd_st.length; i++) { dd_st[i].style.cssText="float:left !important; \ width:160px;\ "; } var dt_st = text_float_stage1.getElementsByTagName('dt'); for (var i=0; i < dt_st.length; i++) { dt_st[i].style.cssText="float:left !important; \ width:120px;\ "; }/**/ var td_1 = document.getElementsByTagName('td'); td_1[0].style.cssText = "width:300px;\ padding-top:21px;\ float:left;\ "; td_1[1].style.cssText = "float:left; \ "; var float_l_stage1 = float_l[1]; var float_l_stage2 = float_l_stage1.children[0]; var float_l_stage3 = float_l_stage2.children[1]; var float_l_stage4 = float_l_stage3.children[0]; float_l_stage4.children[0].style.width = "570px"; float_l_stage4.children[0].style.height = "125px"; var btn = document.getElementById('btn_holder'); var btn_prev = btn.previousElementSibling ; btn.style.cssText="float:left !important; \ "; btn_prev.style.cssText="float:left !important; \ margin-left:250px;\ "; var width_line = document.getElementById('updates'); width_line.children[0].style.cssText = "width:200px;\ "; </script> И все бы хорошо, все работает так как надо КРОМЕ IE ниже 9... Я так понял нельзя использовать cssText , но на что заменить и как? |
Нет, cssText работал всегда. Дело в previousElementSibling, ie<9 не знают такого.
Сразу напишу функцию, но на самом деле лучше вообще не использовать: function prev( el ){ while(el=el.previousSibling) if(el.nodeType === 1) break; return el } |
after_main_stage1.style.cssText = "float:left;\ ";
мне отладчик ИЕ ругается на это и пишет SCRIPT5007: Не удалось получить значение свойства "style": значением объекта является NULL или он не определен Contact Us.htm, строка 229 символ 2 А что с этой функцией написанной вами делать? В смысле где ее вызывать и с какой целью |
Очевидно, что проблема с after_main_stage1, в котором вообще нет style;
Сделайте alert(after_main_stage1)и посмотрите, что он вам напишет. Цитата:
|
Спасибо Aetae за помощь, но вопрос актуален... Получается, что ИЕ видит Коментарии в коде и принимает их как часть кода... Как бы это обойти, может кто подскажет?
|
Цитата:
<!DOCTYPE HTML> <html> <head> </head> <body> <div id='wrapper'> <div>1 </div> <div> 2</div> <div>3 </div> </div> <script> var wrapper_ = document.getElementById('wrapper'); var elem = wrapper_.children[1]; alert(wrapper_.children[3] == null);//wrapper_.children[3] == undefined, a undefined == null wrapper_.insertBefore(elem, wrapper_.children[3]) </script> </body> </html> |
что бы убрать все лишние элементы (комментарии, пробелы и ...) написал функцию remove_TextNode (кроссбраузерно)
<!DOCTYPE HTML> <html> <head> </head> <body> <div id='wrapper'> <div>1 </div> <div> 2</div> <!--text--> <div>3 </div> </div> <script> var wrapper_ = document.getElementById('wrapper'); var divs = wrapper_.getElementsByTagName('div'); console.log(wrapper_.childNodes); console.log( remove_TextNode(wrapper_.childNodes)); function remove_TextNode (array) { var leng = array.length; var elemArray, resultArray = []; for (var i = 0; i < leng;i++) { elemArray = array[i]; if (elemArray.nodeType != 1) continue; resultArray.push(elemArray); } return resultArray; } </script> </body> </html> |
Цитата:
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Документ без названия</title> </head> <body> <div id="content-wrap"> <!--text1--> <div></div> <div></div> <!--text 2 --> <div></div> </div> <script> var wrapper_ = document.getElementById('content-wrap'); /*var elem = wrapper_.children[4];*/ var divs = wrapper_.getElementsByTagName('div'); console.log(wrapper_.childNodes); console.log(remove_TextNode(wrapper_.childNodes)); function remove_TextNode (array) { var leng = array.length; var elemArray, resultArray = []; for (var i = 0; i < leng;i++) { elemArray = array[i]; if (elemArray.nodeType != 1) continue; resultArray.push(elemArray); } return resultArray; } </script> </body> </html> Вот это запускаю в ИЕ и ноль на массу... :( |
я запускал это в ие 8 и все работало
|
cyber,
Не робит ие6-8 |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Документ без названия</title> </head> <body> <div id="content-wrap"> <!--text1--> <div></div> <div></div> <!--text 2 --> <div></div> </div> <script> var wrapper_ = document.getElementById('content-wrap'); /*var elem = wrapper_.children[4];*/ var divs = wrapper_.getElementsByTagName('div'); alert('до обработки ='+wrapper_.childNodes.length+" после="+remove_TextNode(wrapper_.childNodes).length); function remove_TextNode (array) { var leng = array.length; var elemArray, resultArray = []; for (var i = 0; i < leng;i++) { elemArray = array[i]; if (elemArray.nodeType != 1) continue; resultArray.push(elemArray); } return resultArray; } </script> </body> </html> ![]() |
Цитата:
вы правы, не работает, но пародкс в том что alert(wrapper_.children[3] == null);//возвращает true |
cyber, не важно, что он возвращает, важно что IE это не воспринимает)))
|
Цитата:
|
wrapper_.children[3] //undefined, а не null
alert(wrapper_.children[3] === null);//возвращает false alert([ undefined == null, undefined === null ]) |
Цитата:
а можно ссылочку прочитать про то почему они равны, потому что помню что undefined == null, а почему не могу вспомнить |
Потому же почему и
alert(0==false)и alert('' == 0). Приведение типов.) |
Цитата:
Ну если меня память не подводит то в учебнике было написано что они сравниваются "как есть" |
Спасибо за помощь
Сбасибо Aetae и cyber за то, что помогли новичку разобраться в работе с DOM деревом. Итак теперь код, который работает для тех, кто возможно столкнется с подобной задачей
Код:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> function remove_TextNode (array) - для работы с массивом вложенных элементов в том случае, если в коде есть комментарии ( Коменты ИЕ видит как отдельный элемент и поэтому работа под ИЕ и под другими браузерами будет сильно отличаться.) children в ие ниже 9 версии вроде работает( лично у меня работает в 7 и 8 версии) |
хочу уточнить что функции remove_TextNode отсеивает все кроме обьектов (тэгов), т.е удаляет комментарии , текстовые узлы ...
|
Всем доброго время, подскажите пожалуйста как заставить работать такую конструкцию
<script type="text/javascript"> window.onload = afterLoad; function afterLoad() { var maina = document.getElementsByClassName('top_menu_test'); // находим узел var newAttr1 = document.createAttribute('rel'); // создаем атрибут newAttr1.value = 'nofollow'; // устанавливаем значение maina.setAttributeNode(newAttr1); // привязываем атрибут }; </script> <a class="top_menu_test" href="http://mail.ru">http://mail.ru</a> |
var maina = document.getElement*!*s*/!*ByClassName('top_menu_test')*!*[0]*/!*;Elements - множественное число, результат NodeList(массивоподобный объект) и если элемент с таким классом один - значит он там нулевой. А вообще лучше не использовать getElementsByClassName (ибо не работает в ie8), в вашем случае отлично подойдёт: var maina = document.querySelector('.top_menu_test'); |
большое спасибо добрый человек
|
а на будующее не могли бы подсказать пример для такого случая:
<script type="text/javascript"> window.onload = afterLoad; function afterLoad() { var maina = document.querySelectorAll('.top_menu_test'); // находим узел var newAttr1 = document.createAttribute('rel'); // создаем атрибут newAttr1.value = 'nofollow'; // устанавливаем значение maina.setAttributeNode(newAttr1); // привязываем атрибут }; </script> <a class="top_menu_test" href="http://mail.ru">http://mail.ru</a><br> <a class="top_menu_test" href="http://yandex.ru">http://yandex.ru</a><br> <a class="top_menu_test" href="http://google.ru">http://google.ru</a><br> |
Dargonaks,
http://learn.javascript.ru/while-for |
Часовой пояс GMT +3, время: 12:24. |