Выбор нужного элемента дом дерева
Доброго времени суток, вот по чуть учу 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, время: 09:15. |