Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Web программирование > JavaScript, Ajax
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 10.08.2016, 15:03   #1
Viconte
Пользователь
 
Регистрация: 31.08.2010
Сообщений: 40
По умолчанию GetElementsByTagName - живая коллекция или все же нет? (Пример кода)

День Добрый!)
Столкнулся с таким нюансом, getElementsByTagName - возвращает "живую" коллекцию элементов с указанным тегом, для примера - код ниже:

Код HTML:
<ul id="menu">
  <li>Главная страница</li>
  <li>Форум</li>
  <li>Магазин</li>
</ul>
<script>
  var lis = document.body.getElementsByTagName('li');

  document.body.innerHTML = "";

  alert( lis.length ); //0
</script>
Все логично, а теперь посмотрим на такой случай:

Код HTML:
<ul id="menu">
  <li>Главная страница</li>
  <li>Форум</li>
  <li>Магазин</li>
</ul>
<script>
  var lis = document.getElementById('menu').getElementsByTagName('li');

  document.body.innerHTML = "";

  alert( lis.length ); //Результат 3 ?????
</script>


Почему во втором случае мы получаем результат 3, если мы удалили все содержимое блока body!
У кого какие соображения?

Последний раз редактировалось Viconte; 10.08.2016 в 15:34.
Viconte вне форума Ответить с цитированием
Старый 10.08.2016, 15:15   #2
pompiduskus
юзер как все
Участник клуба
 
Аватар для pompiduskus
 
Регистрация: 10.01.2012
Сообщений: 1,586
По умолчанию

Все просто !


Код:
document.body <= не существует!

Попробуйте вот так

Код:
var lis = document.getElementsByTagName('li');
<Дзен - Вся вселенная в тебе > | Резюме: https://ch3ll0v3k.github.io/CV/
pompiduskus вне форума Ответить с цитированием
Старый 10.08.2016, 15:45   #3
Viconte
Пользователь
 
Регистрация: 31.08.2010
Сообщений: 40
По умолчанию

Не совсем то, оба примера правильные - суть в том что коллекция (которую возвращает метод getElementsByTagName)живая - что прекрасно продемонстрировано в первом примере, а вот во втором случае:

Мы удаляем все содержимое элемента body(вместе с li):
Код:
var lis = document.getElementById('menu').getElementsByTagName('li');
document.body.innerHTML = "";
И по логике в результатет у нас коллекция lis должна быть пустая, но нет - она сосотоит из все тех же трех элементов li
Вопрос - почему коллекция не очищается?
Viconte вне форума Ответить с цитированием
Старый 10.08.2016, 16:03   #4
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,238
По умолчанию

Viconte, всё верно.
метод getElementsByTagName() method returns a live HTMLCollection (возвращает "живую" коллекцию).
метод getElementById возвращает объект (не "живой", поэтому он не меняется при изменении в DOM)

посмотрите, например,
http://xahlee.info/js/js_get_elements.html
какие методы возвращают "LIVE"

p.s. кстати, я с JS не очень, поэтому раньше про live HTMLCollection не знал!

а ещё рассмотрите такой пример:

Код:
<html>
<ul id="menu">
  <li>Главная страница</li>
  <li>Форум</li>
  <li>Магазин</li>
</ul>
<script>
  var lis = document.getElementsByTagName('li');
  var mobj = document.getElementById('menu'); 
  var lis2 = mobj.getElementsByTagName('li');

  alert('before lis= ' + lis.length+' lis2 '+lis2.length ); 

  mobj.innerHTML = "";

  alert('after lis= ' + lis.length+' lis2 '+lis2.length ); 

</script>
</html>

Последний раз редактировалось Serge_Bliznykov; 10.08.2016 в 16:21.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 10.08.2016, 16:51   #5
Viconte
Пользователь
 
Регистрация: 31.08.2010
Сообщений: 40
По умолчанию

Serge_Bliznykov, Выяснил кое-что:

Все мы знаем что getElementsByTagName - возвращает HTMLCollection ("живую коллекцию")

Давайте возьмем такую страницу HTML:

Код HTML:
<div id="box">
  <ul id="menu">
    <li>Главная страница</li>
    <li>Форум</li>
    <li>Магазин</li>
  </ul>
</div>
а теперь попробуем два варианта,

Первый вариант (сделаем innerHTML непосредственно у элемента menu, к которому и применяем метод getElementsByTagName):

Код:
var menu = document.getElementById('menu'),
      li = menu.getElementsByTagName('li');

menu.innerHTML = '';
    
console.log(li.length)// 0 - коллекция и правда живая
Все хорошо, а теперь второй случай,

Второй вариант (сделаем innerHTML у родителя menu):

Код:
    
var box = document.getElementById('box'),
      menu = document.getElementById('menu'),
      li = menu.getElementsByTagName('li');
    
box.innerHTML = '';
    
console.log(li.length)// 3 - коллекция НЕживая
Как это можно объяснить?)

Последний раз редактировалось Viconte; 10.08.2016 в 16:58.
Viconte вне форума Ответить с цитированием
Старый 10.08.2016, 17:04   #6
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,238
По умолчанию

я же повторяю, я в JS не компетентен.

Цитата:
Как это можно объяснить?)
ну, например, тем, что когда Вы делаете box.innerHTML = '';
переменная menu никак не изменяется (можете сами в отладчике посмотреть и убедится в этом)! а live (динамическая) коллекция в данном случае берётся именно от menu.


Код:
box.innerHTML = '';
document.body.innerHTML=menu.innerHTML;

Последний раз редактировалось Serge_Bliznykov; 10.08.2016 в 17:08.
Serge_Bliznykov вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Есть ли у кого пример кода распаковки и запаковки zip или 7z с прогресс баром? Raf-9600 C# (си шарп) 1 25.11.2015 23:54
Inline Method пример кода..? Masarr Общие вопросы C/C++ 5 03.12.2010 13:55
Правильно или нет вот в чём вопрос но ошибок нет... Alexcool Помощь студентам 2 10.01.2010 13:55
Как проверить все ли ячейки в StringGrid заполнены или нет ? Ветас Помощь студентам 4 11.11.2009 22:54
SMTP + SSL пример кода dimonbest Работа с сетью в Delphi 8 15.08.2008 10:56