Полезная информация

Будьте в курсе последних изменений в мире Mozilla, следя за нашим микроблогом в Twitter.

№104-04-2006 11:12:34

O.Nick
Участник
 
Группа: Members
Откуда: Москва
Зарегистрирован: 19-05-2005
Сообщений: 106
Веб-сайт

Ссылки в JS на элементы DOM

Хочу перебрать в цикле все элементы <span>, у которых внутри есть какой-то текст. Первый <span> имеет id="start", остальные его не имеют (т.к. их дофига).
если я обращаюсь к полю id.firstChild.innerHTML, то весь текст доступен, если же пробую сделать перебор с помощью временной переменной node:

Выделить код

Код:

var node = start;
 while (node != null)
 {
  var text = node.firstChild.innerHTML;
  if(text.indexOf(... // то выполняются какие-то действия
  node = node.nextSibling;
 }

то начинают ругаться нато, что у node нет поля firstChild.
Что я делаю неправильно? Буду благодарен любым замечаниям.

Отсутствует

 

№204-04-2006 13:39:42

Yan
Участник
 
Группа: Extensions
Откуда: Москва
Зарегистрирован: 27-02-2005
Сообщений: 1019

Re: Ссылки в JS на элементы DOM

O.Nick

если я обращаюсь к полю id.firstChild.innerHTML...

Правильно будет обращаться document.getElementById('start').

начинают ругаться нато, что у node нет поля firstChild

При переборе всех узлов через nextSibling между span'ами вполне могут быть текстовые узлы, у которых само собой нет firstChild. Так что правильно будет проверять, что nodeName у элемента равно SPAN. Также у пустого SPAN может не быть firstChild, так что лучше это проверить с помощью hasChildNodes(). Можно так же еще проверить, что firstChild является текстом через node.firstChild.nodeType==3.

Хочу перебрать в цикле все элементы <span>, у которых внутри есть какой-то текст. Первый <span> имеет id="start", остальные его не имеют (т.к. их дофига).

Не очень понятно, нужно перебрать только "братков" у "start", или все SPAN, начиная со "start"? Если второе, то легче воспользоваться document.getElementsByTagName('SPAN') и при переборе выставить "флаг" при нахождении "start". (Если вообще нужны все SPAN, то можно и без флага)

В общем, на примере понятней:

Выделить код

Код:

<html>
<body>
<script type="text/javascript">
function select_siblings(){
 var ar=new Array;
 var node = document.getElementById('start');
 while (node!=null)
 {
  if (node.nodeName=='SPAN'&&node.hasChildNodes()&&node.firstChild.nodeType==3)
  {
   var text = node.firstChild.nodeValue;
   ar.push(text);
   //if(text.indexOf(... // то выполняются какие-то действия
  }
  node = node.nextSibling;
 }
 alert(ar);
}
function select_spans_after_start(){
 var ar=new Array;
 var spans = document.getElementsByTagName('SPAN');
 var flag=false;
 for(i=0; i<spans.length; i++)
 {
  if (spans[i].getAttribute('id')=='start') flag=true;
  if (flag==true&&spans[i].hasChildNodes()&&spans[i].firstChild.nodeType==3)
  {
   var text = spans[i].firstChild.nodeValue;
   ar.push(text);
  }
 }
 alert(ar);
}
function select_all_spans(){
 var ar=new Array;
 var spans = document.getElementsByTagName('SPAN');
 for(i=0; i<spans.length; i++)
 {
  if (spans[i].hasChildNodes()&&spans[i].firstChild.nodeType==3)
  {
   var text = spans[i].firstChild.nodeValue;
   ar.push(text);
  }
 }
 alert(ar);
}

</script>
<div>
 <span>1</span>
 <span>2</span>
 <span></span>
 <span>3</span>
</div>
<div>
 <span id="start">a</span>
 <span>b</span>
 <span></span>
 <span><span></span></span>
 <span>c</span>
</div>
<div>
 <span>x</span>
 <span>y</span>
 <span></span>
 <span>z</span>
</div>
<div>
 <input type="button" onclick="select_siblings();" value="Перебрать всех 'братков' у 'start'">
 <br>
 <input type="button" onclick="select_spans_after_start();" value="Перебрать все SPAN после 'start'">
 <br>
 <input type="button" onclick="select_all_spans();" value="Перебрать все SPAN'ы">
</div>
</body>
</html>

Отсутствует

 

№304-04-2006 17:27:52

O.Nick
Участник
 
Группа: Members
Откуда: Москва
Зарегистрирован: 19-05-2005
Сообщений: 106
Веб-сайт

Re: Ссылки в JS на элементы DOM

Спасибо!
Свою ошибку понял. Поиск по span был нужен здесь: lermont.ru/all.php

Отсутствует

 

№404-04-2006 17:32:23

Anton
Участник
 
Группа: Extensions
Откуда: от верблюда
Зарегистрирован: 14-12-2004
Сообщений: 3057
Веб-сайт

Re: Ссылки в JS на элементы DOM

p.s.
А ещё есть XPath. Вот html Yan'а, использующий XPath:

Выделить код

Код:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
  "http://www.w3.org/TR/html4/loose.dtd">
<html>
<body>
<script type="text/javascript">
function resultHandlerFunction (xpathRes)
{
    var ar = new Array ();
    for (var i = 0; i < xpathRes. snapshotLength; i++)
        ar. push (xpathRes. snapshotItem (i). textContent);
    alert (ar);
}
function do_xpath_query (query, resultHandler)
{
    var elements = document. evaluate
    (
        query,
        document,
        null,
        XPathResult. UNORDERED_NODE_SNAPSHOT_TYPE,
        null
    );
    resultHandler (elements);
}
function select_siblings()
{
    do_xpath_query
    (
        /*"//span[@id='start']/following-sibling::span[text()]"*/ // - кроме <span id="start">
        "//span[@id='start']/../span[text()]",
        resultHandlerFunction
    );
}
function select_spans_after_start()
{
    do_xpath_query (
        /*"//span[@id='start']/following::span[text()]"*/  // - кроме <span id="start">
        "//span[@id='start']|//span[@id='start']/following::span[text()]",
        resultHandlerFunction
    );
}
function select_all_spans()
{
    do_xpath_query ("//span[text()]", resultHandlerFunction);
}
</script>
<div>
 <span>1</span>
 <span>2</span>
 <span></span>
 <span>3</span>
</div>
<div>
 <span id="start">a</span>
 <span>b</span>
 <span></span>
 <span><span></span></span>
 <span>c</span>
</div>
<div>
 <span>x</span>
 <span>y</span>
 <span></span>
 <span>z</span>
</div>
<div>
 <input type="button" onclick="select_siblings();" value="Перебрать всех 'братков' у 'start'">
  <br>
 <input type="button" onclick="select_spans_after_start();" value="XPath: Перебрать все SPAN после 'start'">
  <br>
 <input type="button" onclick="select_all_spans();" value="Перебрать все SPAN'ы">
 </div>
</body>
</html>

Время настанет, время придет...
И лис кОнкурiентов на части порвет !!!

Отсутствует

 

№512-07-2006 12:01:57

O.Nick
Участник
 
Группа: Members
Откуда: Москва
Зарегистрирован: 19-05-2005
Сообщений: 106
Веб-сайт

Re: Ссылки в JS на элементы DOM

Снова возвращаюсь в эту старую ветку, т.к. появились некоторые новости. Все по порядку.
Преамбула. За основу взял код, который привел Yan:

Выделить код

Код:

var node = document.getElementById('start');
 while (node!=null)
 {
  if (node.nodeName=='SPAN'&&node.hasChildNodes()&&node.firstChild.nodeType==3)
  {
   var text = node.firstChild.nodeValue;
   ar.push(text);
   //if(text.indexOf(... // то выполняются какие-то действия
  }
  node = node.nextSibling;
 }
}

Но "оптимизировал" т.к.  заложился на внутреннюю структуру того, что лежит внутри <span> - а эта структура не будет менятся ни при каких обстоятельствах.
Получилось так:

Выделить код

Код:

while (node != null)
 {
  if(node.nodeName == "SPAN")
  {
   var text = node.firstChild.firstChild.innerHTML; // закладывается на структуру
   if(filter == "" || text.indexOf(filter) != -1)  // оставляем видимыми только те <span>, которые внутри содержат текст из переменной filter   
    node.style.display = "inline";
   else
    node.style.display = "none";
   if(gTimeout != 0) // служебная проверка
    break;
  }
  node = node.nextSibling;
 }

Код реализован на ОЧЕНЬ большой странице (270K) http://lermont.ru/all.php, функция ApplyFilter из filter.js

Амбула. Добавил таймер работы фильтра и прогнал эту страницу в Firefox 1.5, IE6 и Opera 9 - посмотрел на результаты и тихо офигел - Firefox тормозит сильнее всех. Как я проверял - для каждого браузера делал 2 замера, первый, когда в строку фильтра вводится текст, которого заведомо нет ни в одном теге - zzz, в этом случае перебирается около 3000 тегов (узлы <span>) и у них выставляется display = "none". Примерное время по браузерам:
Firefox - 0.922 сек
IE - 15.484 сек 
Opera - 0.359 сек
Второе действие - обратное, затираем в строке фильтра zzz, чтобы она стала пустой. При этом вновь перебираются эти же 3000 тегов и у них выставляем display = "inline". Примерное время по браузерам:
Firefox - 6.828 сек
IE - 15.360 сек
Opera - 0.609 сек
Второе время, которое показывает Firefox - не соответствует действительности, после того, как высвечивается надпись 6.828 сек, проходит еще секунд 40, пока появятся теги.
Как-то обидно за любимый браузер. Если кто поможет советом как ускорить скрипт в Firefox и как пофиксить замер времени под Firefox - буду очень благодарен.

Отредактировано O.Nick (12-07-2006 12:04:10)

Отсутствует

 

№612-07-2006 13:51:56

O.Nick
Участник
 
Группа: Members
Откуда: Москва
Зарегистрирован: 19-05-2005
Сообщений: 106
Веб-сайт

Re: Ссылки в JS на элементы DOM

Несколько оптимизировал страницу - убрал промежуточные текстовые узлы между <span>, теперь при втором замере Firefox пишет, что отобразил все теги за 0.844 сек, но реально отображает где-то за 40-50 секунд.

Отсутствует

 

Board footer

Powered by PunBB
Modified by Mozilla Russia
Copyright © 2004–2020 Mozilla Russia GitHub mark
Язык отображения форума: [Русский] [English]