Статьи

HTML заголовки теги не знают, что они больше

В прошлые выходные я решил написать пост для этого сайта. В ходе работы над этим я снова столкнулся с этой старой проблемой и был поглощен попытками ее решить. У меня были некоторые идеи об этом пару лет назад, но я никогда не пытался их опробовать. В результате получается эта публикация вместо той, которую я изначально намеревался написать. Я все еще доберусь до этого поста позже ….

Что не так с тегами заголовков?

Семантическая разметка

В течение некоторого времени нам говорили, что мы не должны использовать HTML-теги для прямого форматирования контента. Вместо этого мы должны использовать теги в качестве разделителей для разных видов контента, а затем мы должны использовать эти теги-разделители для форматирования контента с помощью селекторов CSS. Идея заключается в том, что теги являются формой семантической разметки, и мы используем эту технику, чтобы отделить контент от представления. (Если вы не знакомы с этой концепцией, вы можете почувствовать ее, посетив CSS Zen Garden .)

Теория хороша: вы должны иметь возможность использовать CSS для изменения содержания на вашем сайте любым способом. Однажды я работал над большой системой публикаций в СМИ, которая извлекла бы выгоду из этого, делая новости доступными в форме чистого NewsML , тем самым позволяя различным свойствам форматировать их в соответствии с внешним видом их страниц.

Содержание в стиле учебника

Содержание в стиле учебника разбито на разделы. Разделы могут иметь подразделы, которые, в свою очередь, могут иметь больше подразделов. Вот некоторые примеры:

В этих примерах не используются вложенные разделы, но я столкнулся с рядом случаев, когда я хотел это сделать. Я сделал это на этой странице, чтобы продемонстрировать эффект.

HTML заголовки тегов

Я склонен писать много вики-документации для проектов, над которыми я работаю, и мне нравится использовать стиль учебника, описанный выше. Эта документация создана вручную в целевой вики. Разделы полезны, потому что они полезны для обозначения понятий, и я создаю заголовки разделов под названием якоря, чтобы я мог отправлять людям ссылки на них.

HTML предоставляет то, что я буду называть тегами заголовков: <h1> — <h6>.

Похоже, это то, что мне нужно использовать для достижения этого эффекта. Каждый раздел возглавляется одним из них. Однако, оглядываясь назад, они нарушают принцип семантической разметки, описанный выше. Я не знал об этом сначала. Некоторое время я использовал их, но заметил, что редактирование документов, над которыми я работал, связано с различной степенью боли из-за этих тегов. Я обнаружил, что буду перемещать разделы, иногда беря раздел верхнего уровня, и превращая его в раздел другого. Или, иногда наоборот: возьмите подраздел и сделайте его разделом верхнего уровня.

Эти перемещения по разделам были болезненными, потому что мне пришлось бы выискивать теги заголовков и корректировать их: при перемещении подраздела <h3> вверх на уровень я должен помнить, чтобы изменить его на <h2>. Это подвержено ошибкам: иногда я пропускаю их в плоском списке, в котором они появились. Или иногда я забываю преобразовать закрывающий тег.

Теги заголовков HTML не просто семантические

Недавно я понял, что использование тегов заголовков граничит с указанием форматирования. О, это не так специфично, как настройка размера шрифта с помощью чего-то вроде тега <font> (теперь считается большим нет-нет). Но заголовочные теги определяют уровень контента. И уровень можно определить из структуры документа — мы не должны полагаться на людей в этом. Если уровень был выведен из структуры документа, то авторы могли бы перемещать контент по своему усмотрению, не беспокоясь о том, чтобы указать (или изменить), на каком уровне он находится.

В результате теги заголовков не просто говорят «это заголовок», что будет чистой семантической разметкой. Они говорят «это заголовок на уровне 3» или на любом другом уровне, и это подразумевает разницу в форматировании.

HTML5 на помощь?

Когда я снова столкнулся с этой старой проблемой, мне пришло в голову, что HTML5, наконец, мог что-то с этим сделать. Поэтому я сделал несколько быстрых поисков. Вот что я обнаружил:

  • Как Google интерпретирует несколько тегов H1 во вложенных разделах HTML5?
    Звучит многообещающе. Кажется, подразумевается, что новый тег <section> позволяет всем заголовкам быть <h1>, решая мою проблему.
  • html5 Doctor: элемент section
    Вы не должны использовать <section> для содержимого, которое нужно стилизовать. Разве это не все?
  • Когда использовать элемент HTML5 «section»
    Я запутался. «… пронумерованные разделы диссертации» звучит так, как я хочу. Но у нас все еще есть «… стилизация … вместо этого используйте элемент div». Эта страница, кажется, идет вперед и назад. Наконец, «Просмотр источника» показывает, что эта страница не использует <section>, и имеет три разных уровня тегов заголовков для заголовков «раздела» в контенте. Видимо, эти эксперты не верят, что для этого следует использовать <section>.

Последний случай убедил меня, и я пришел к выводу, что эта проблема до сих пор не решена.

Заменитель заголовков

Мои требования просты: я должен иметь возможность разметить разделы в своем документе как разделы и указать, каким должен быть заголовок раздела. Эта разметка должна быть независимой от того, где в документе появляется раздел.

Отказ от ответственности: я парень из серверного типа и определенно не ниндзя DHTML / JavaScript. Может быть, есть решение или лучшие ответы на этот вопрос, но это не совсем моя задача, и я просто балуюсь этим, когда мне это нужно. Если вы знаете лучшие способы сделать это, пожалуйста, дайте мне знать.

Самая простая вещь, о которой я мог подумать, выглядит так:

<div class="sectiontoc-section">
<span class="sectiontoc-title">Section Title Goes Here</span>
<p>Section content goes here...</p>
 
<div class="sectiontoc-section"> <!-- you can nest sections -->
<span class="sectiontoc-title">Subsection Title Goes Here</span>
<p>Subsection content goes here...</p>
</div>
</div>

 

Чтобы заставить его работать, мне просто нужно создать стили для классов в разметке.

Однако не все так просто. Я хотел использовать эту схему на этом сайте, который генерируется Drupal . Я использую консервированную тему, которую я скачал, и у нее уже есть таблица стилей для них. Я не хочу дублировать все стили тегов заголовков на наборах вложенных селекторов классов. Что если они изменятся? Что если я хочу использовать это с другой темой?

Я могу воспользоваться существующими стилями, если смогу превратить разметку выше в теги заголовков. Но я не хочу делать это вручную. Итак, JavaScript на помощь: я написал несколько функций, чтобы пройти через <div> выше и заменить <span> тегами заголовков, основываясь на их глубине в разделах.

Я создал тестовую страницу, которую я мог загрузить локально через file: //, чтобы протестировать JavaScript:

  • article.html
    Тестовая страница статьи
  • bobt.js
    JavaScript для преобразования разметки

В то же время я воспользовался своей прогулкой по разделам, чтобы (необязательно) создать мини-оглавление, которое ссылается на заголовки разделов через именованные якоря. Даже если бы я использовал таблицу стилей для заголовков, мне все равно пришлось бы делать что-то подобное в JavaScript.

Drupal Integration

После того, как у меня появился пример JavaScript выше, я решил, что мои проблемы прошли. К сожалению, мне пришлось выяснить, как загрузить это для сайта Drupal.

К сожалению, большая часть документации Drupal о том, как написать PHP для генерации контента для модуля. Все, что мне нужно, это загрузить файл .js и событие onload, чтобы вызвать его, чтобы преобразовать страницу. Drupal довольно интенсивно использует jQuery , и вы должны интегрироваться с ним. Единственной ссылкой, которую я нашел, было Управление JavaScript в Drupal 7 , которое указывало на несколько примеров. После просматривал те, и части Создание модулей Drupal 7.x .

В моей первой попытке подключить это я просто трансплантировал приведенный выше код в поведение Drupal для $ (document) .ready (…), но это не сработало. Немного покопавшись в этом, я обратился за помощью к страницам Drupal и drupal.stackexchange.com , но никто не смог мне помочь. Пройдя немного дальше, я смог использовать отладчик Chrome JavaScript, чтобы увидеть, что происходит, и обнаружил, что многие из моих переменных не определены. По-видимому, jQuery не понравится, если вы используете простые старые методы DOM изнутри.

Я просмотрел несколько учебников по jQuery в Интернете. Я преобразовал свой исходный JavaScript-код, чтобы циклы были заменены селекторами jQuery, а тела циклов стали анонимными функциями. Я сделал это за пределами Drupal, и в итоге получилось следующее:

  • jqarticle.html
    jQuery тестовая страница статьи
  • jqbobt.js
    jQuery JavaScript для преобразования разметки

Чтобы заставить его работать, мне пришлось обернуть весь контент еще одним <div>, чтобы я мог понять глубину содержания; мое первоначальное предположение, что они будут находиться непосредственно внутри <body>, было неверным в контексте Drupal. Это сделало конечный результат похожим на это:

<div id="sectiontoc-body">
<div id="sectiontoc-toc"><!-- placeholder for table of contents --></div>
 
<div class="sectiontoc-section">
<span class="sectiontoc-title">Section Title Goes Here</span>
<p>Section content goes here...</p>
 
<div class="sectiontoc-section"> <!-- you can nest sections -->
<span class="sectiontoc-title">Subsection Title Goes Here</span>
<p>Subsection content goes here...</p>
</div>
</div>
</div> <!-- secctiontoc-body -->

Наконец, я собрал модуль Drupal , установил его обычным способом, включил его и вуаля! Если вы посмотрите исходный код на этой странице, то увидите, что я использовал разделы и классы в разметке; отображаемая страница использует соответствующие заголовки, при этом автор не должен знать их глубину при создании. Страница имеет оглавление вверху, и они связаны с именованными якорями в теле.