В прошлые выходные я решил написать пост для этого сайта. В ходе работы над этим я снова столкнулся с этой старой проблемой и был поглощен попытками ее решить. У меня были некоторые идеи об этом пару лет назад, но я никогда не пытался их опробовать. В результате получается эта публикация вместо той, которую я изначально намеревался написать. Я все еще доберусь до этого поста позже ….
Что не так с тегами заголовков?
Семантическая разметка
В течение некоторого времени нам говорили, что мы не должны использовать HTML-теги для прямого форматирования контента. Вместо этого мы должны использовать теги в качестве разделителей для разных видов контента, а затем мы должны использовать эти теги-разделители для форматирования контента с помощью селекторов CSS. Идея заключается в том, что теги являются формой семантической разметки, и мы используем эту технику, чтобы отделить контент от представления. (Если вы не знакомы с этой концепцией, вы можете почувствовать ее, посетив CSS Zen Garden .)
Теория хороша: вы должны иметь возможность использовать CSS для изменения содержания на вашем сайте любым способом. Однажды я работал над большой системой публикаций в СМИ, которая извлекла бы выгоду из этого, делая новости доступными в форме чистого NewsML , тем самым позволяя различным свойствам форматировать их в соответствии с внешним видом их страниц.
Содержание в стиле учебника
Содержание в стиле учебника разбито на разделы. Разделы могут иметь подразделы, которые, в свою очередь, могут иметь больше подразделов. Вот некоторые примеры:
- CSS Zen Garden
На странице есть несколько разделов, разделенных заголовками разделов. - Управление JavaScript в Drupal 7
На странице есть несколько разделов, снова разделенных заголовками. - Золотое правило указателей
Страница с этого сайта, которая снова демонстрирует ту же общую структуру.
В этих примерах не используются вложенные разделы, но я столкнулся с рядом случаев, когда я хотел это сделать. Я сделал это на этой странице, чтобы продемонстрировать эффект.
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 , установил его обычным способом, включил его и вуаля! Если вы посмотрите исходный код на этой странице, то увидите, что я использовал разделы и классы в разметке; отображаемая страница использует соответствующие заголовки, при этом автор не должен знать их глубину при создании. Страница имеет оглавление вверху, и они связаны с именованными якорями в теле.