JavaScript. Подробное руководство, 6-е издание, стр. 216

<b>  // Отыскать все элементы заголовков разделов </b>

<b>  var headings;</b>

<b>  if (document.querySelectorAll) // Возможно есть более простой путь?</b>

<b>    headings = document.querySelectorAll(”h1,h2,h3.h4, h5. h6”);</b>

<b>  else // Иначе отыскать заголовки более сложным способом</b>

<b>    headings = findHeadings(document.body, []);</b>

<b>  // Выполняет рекурсивный обход тела документа в поисках заголовков </b>

<b>  function findHeadings(root, sects) {</b>

<b>    for(var с = root.firstChild; c != null; c = c.nextSibling) {</b>

<b>      if (c.nodeType !== 1) continue;</b>

<b>      if (c.tagName.length == 2 &amp;&amp; c.tagName.charAt(O) == &quot;H&quot;)</b>

<b>        sects.push(c);</b>

<b>      else</b>

<b>        findHeadings(c, sects);</b>

<b>    }</b>

<b>    return sects;</b>

<b>  }</b>

<b>  // Инициализировать массив, хранящий номера разделов, </b>

<b>  var sectionNumbers = [0,0,0,0,0,0];</b>

<b>  // Выполнить цикл по найденным элементам заголовков.</b>

<b>  for(var h = 0; h &lt; headings.length; h++) {</b>

<b>    var heading = headings[h];</b>

<b>    // Пропустить заголовки, находящиеся в контейнере оглавления,</b>

<b>    if (heading.parentNode == toc) continue;</b>

<b>    // Определить уровень заголовка.</b>

<b>    var level = parseInt(heading.tagName.charAt(1));</b>

<b>    if (isNaN(level) || level &lt; 1 || level &gt; 6) continue;</b>

<b>    // Увеличить номер раздела для этого уровня и установить</b>

<b>    // номера разделов более низкого уровня равными нулю.</b>

<b>    sectionNumbers[level-1]++;</b>

<b>    for(var і = level; і &lt; 6; і++) sectionNumbers[i] = 0;</b>

<b>    // Объединить номера разделов всех уровней,</b>

<b>    // чтобы получился номер вида 2.3.1.</b>

<b>    var sectionNumber = sectionNumbers.slice(0,level).join(&quot;.&quot;)</b>

<b>    // Добавить номер раздела в заголовок. Номер помещается в элемент &lt;span&gt;,</b>

<b>    // чтобы его можно было стилизовать с помощью CSS.</b>

<b>    var span = document.createElement(&quot;span&quot;);</b>

<b>    span.className = &quot;TOCSectNum&quot;;</b>

<b>    span.innerHTML = sectionNumber;</b>

<b>    heading.insertBefore(span, heading.firstChild);</b>

<b>    // Обернуть заголовок якорным элементом, чтобы можно было</b>

<b>    // сконструировать ссылку на него.</b>

<b>    var anchor = document.сreateElement(&quot;а&quot;);</b>

<b>    anchor.name = &quot;TOC&quot;+sectionNumber;</b>

<b>    heading.parentNode.insertBefore(anchor, heading);</b>

<b>    anchor.appendChild(heading);</b>

<b>    // Создать ссылку на этот раздел,</b>

<b>    var link = document.createElement(&quot;а&quot;);</b>

<b>    link.href = &quot;#T0C&quot; + sectionNumber; // Адрес назначения ссылки </b>

<b>    link.innerHTML = heading.innerHTML; // Текст ссылки совпадает</b>

<b>                                        // с текстом заголовка</b>

<b>    // Поместить ссылку в элемент div, чтобы обеспечить возможность</b>

<b>    // стилизации в зависимости от уровня.</b>

<b>    var entry = document.сreateElement(&quot;div&quot;);</b>

<b>    entry.className = &quot;TOCEntry TOCLevel&quot; + level;</b>

<b>    entry.appendChild(link);</b>

<b>    // И добавить элемент div в контейнер оглавления, </b>

<b>    toc.appendChild(entry);</b>

<b>  }</b>

<b>});</b>

15.8. Геометрия документа и элементов и прокрутка

До сих пор в этой главе мы рассматривали документы как некие абстрактные деревья элементов и текстовых узлов. Но когда броузер отображает документ в своем окне, он создает визуальное представление документа, в котором каждый элемент имеет определенную позицию и размеры. Часто веб-приложения могут интерпретировать документы как деревья элементов и никак не заботиться о том, как эти элементы отображаются на экране. Однако иногда бывает необходимо определить точные геометрические характеристики элемента. Например, в главе 16 мы увидим, что элемент можно поместить в определенную позицию с помощью CSS. Если вам потребуется использовать CSS для динамического позиционирования элемента (такого как всплывающая подсказка или сноска) рядом с элементом, который позиционируется броузером, вам необходимо иметь возможность определять положение этого элемента.