#javascript #java #accessibility #html-heading
Вопрос:
Мы внедряем доступность на нашем сайте. Поскольку контент на сайте является авторским, одним из требований, заданных клиентом, было получение информации о том, пропускаются ли теги заголовка на странице. Например. если тег h3 используется после h1 вместо h2. Пожалуйста, дайте мне знать, если это можно сделать предпочтительно на Javascript/Java.
Комментарии:
1. Что вы имеете в виду под»Явой»? Java в браузере была удалена почти из каждого браузера.
Ответ №1:
Чтобы проверить пропущенные уровни заголовков, вам нужно просмотреть заголовки на странице и убедиться, что они либо:
- оставайтесь на том же (том же уровне)
- уменьшение (резервное копирование одного или нескольких уровней)
- увеличение (только на один).
Если ни одно из вышеперечисленного не соответствует действительности, то у вас есть ошибка.
Приведенный ниже фрагмент кода проверит все это, а затем вернет массив элементов для отладки.
Возвращаемые поля являются:
- Предыдущий уровень заголовка: предыдущий правильный уровень заголовка, чтобы вы могли проверить вложенность (полезно посмотреть, действительно ли ошибка заключается в том, что этот уровень заголовка неверен и должен быть на один уровень ниже!),
- seenHeadingLevel: уровень заголовка, который мы видели,
- Ожидаемый уровень заголовка: уровень заголовка, который мы ожидали увидеть,
- seenHeadingText: текст заголовка, который пропустил уровень заголовка, чтобы вы могли его найти.,
- Предыдущий заголовок: текст предыдущего заголовка, чтобы вы могли легко найти его на странице.
Использование
Чтобы использовать следующий фрагмент кода, вы можете вызвать его checkheadings()
для проверки всего документа.
В качестве альтернативы вы можете вызвать его при передаче допустимой querySelector
переменной, например, .myClass
для проверки только в пределах определенного элемента (полезно для сложных документов).
Пожалуйста, обратите внимание: Поскольку технически допустимо иметь более одного <h1>
документа в документе, это не проверяется, однако стоит отметить, что считается хорошей практикой иметь только один <h1>
на странице.
Пример кода
function getHeadingLevel(heading) {
return parseInt(heading.tagName[1]);
}
function createError(expectedHeadingLevel, previousHeadingLevel, previousHeadingText, currentHeadingLevel, currentHeadingText){
var err = {};
err.previousHeadingLevel = (previousHeadingLevel == 0) ? "no previous headings" : previousHeadingLevel;
err.seenHeadingLevel = currentHeadingLevel;
err.expectedHeadingLevel = expectedHeadingLevel;
err.seenHeadingText = currentHeadingText;
err.previousHeadingText = previousHeadingText;
return err;
}
function checkheadings(container) {
container = container || 'body';
var cont = document.querySelector(container);
var headings = cont.querySelectorAll("h1, h2, h3, h4, h5, h6");
var errors = [];
var previousHeadingLevel = 0;
var previousHeadingText = "Document Start - no headings yet";
if (headings.length < 1) {
errors.push("no headings detected");
return errors;
}
for (x = 0; x < headings.length; x ) {
var currentHeadingLevel = getHeadingLevel(headings[x]);
var currentHeadingText = headings[x].textContent;
var expectedHeadingLevel = previousHeadingLevel 1;
if (currentHeadingLevel > expectedHeadingLevel) {
//errors.push("H" expectedLevel " skipped. Previous correct heading was H" previousHeadingLevel " containing text:" previousHeadingText ". Unexpected H" currentHeadingLevel " text: " currentHeadingText);
errors.push(createError(expectedHeadingLevel, previousHeadingLevel, previousHeadingText, currentHeadingLevel, currentHeadingText));
continue;
}
previousHeadingLevel = currentHeadingLevel;
previousHeadingText = currentHeadingText;
}
return errors;
}
console.log("1 error", checkheadings('.test1'));
console.log("3 errors", checkheadings('.test2'));
console.log("no errors", checkheadings('.test3'));
console.log("entire document", checkheadings());
<div class="test1">
<h1>h1-1</h1>
<h2>h2-1</h2>
<h4>h4-1 - skipped</h4>
<h3>h3-1</h3>
<h2>h2-2</h2>
<h3>h3-2</h3>
<h2>h2-2</h2>
<h2>h2-3</h2>
<h3>h3-3</h3>
</div>
<div class="test2">
<h2>h2 - skipped</h2>
<h1>h1-1</h1>
<h4>h4-1 - skipped</h4>
<h3>h3-1 - skipped</h3>
</div>
<div class="test3">
<h1>h1-1</h1>
<h2>h2-1</h2>
<h3>h3-1</h3>
<h2>h2-2</h2>
<h3>h3-2</h3>
<h2>h2-3</h2>
<h3>h3-3</h3>
<h4>h4-1</h4>
<h5>h5-1</h5>
</div>
Комментарии:
1. Это очень хороший служебный скрипт. Отличная работа! Когда я тестировал (в chrome), он продолжал выдавать ошибки
cont.querySelectorAll
, но изменениеcont
наdocument
заставило все работать. Несколько мыслей по этому поводу: (1) сценарии могут сообщить вам, пропущены ли уровни, но ни один алгоритм не может определить, используется ли правильный уровень заголовка — это требует проверки человеком, и (2) элементы секционирования могут изменить ожидаемый поток, тем самым давая ложные срабатывания. Отличный ответ.2. Как странно, он выдал ошибку, я только построил его в скрипке, так что я предполагаю, что это как-то связано с по умолчанию
document.querySelector('body');
(или вы его назвали с селектором?) — Я только построили его таким образом для демонстрации (чтобы я мог запускать сценарии 3) и на возможность тестировать разделы, я буду видеть, если я могу это исправить. Отличные моменты в отношении 2-х необходимых битов человеческой проверки! Теперь я ломаю голову над тем, могу ли я также учитывать элементы секционирования 😋
Ответ №2:
Напишите базовый веб-искатель java https://mkyong.com/java/jsoup-basic-web-crawler-example/ и с помощью Jsoup вы можете выполнить синтаксический анализ
// Group of all h-Tags
Elements hTags = doc.select("h1, h2, h3, h4, h5, h6");
// Group of all h1-Tags
Elements h1Tags = hTags.select("h1");
// Group of all h2-Tags
Elements h2Tags = hTags.select("h2");
// ... etc.
Убедитесь, что у нас есть несколько H1, что также является проблемой в SEO
Ответ №3:
Вы можете использовать document.querySelectorAll("h1, h2, h3, h4, h5, h6")
, а затем проанализировать полученный список узлов.
Я не уверен, как выглядит ваш желаемый результат. Этот фрагмент кода вернет массив с номерами всех пропущенных файлов. Также он ожидает только одного h1, h2, … соответственно.
const headings = document.querySelectorAll("h1, h2, h3, h4, h5, h6")
const getHeadingNumber = (heading) => parseInt(heading.tagName[1])
let lastHeadingNumber;
const skippedHeadings = []
for (let heading of headings) {
if(!lastHeadingNumber) {
lastHeadingNumber = getHeadingNumber(heading)
continue;
}
const currentHeadingNumber = getHeadingNumber(heading)
const expectedHeadingNumber = lastHeadingNumber 1
if(expectedHeadingNumber !== currentHeadingNumber) {
skippedHeadings.push(expectedHeadingNumber)
}
lastHeadingNumber = currentHeadingNumber;
}
console.log(skippedHeadings)
<h1></h1>
<h3></h3>
<h5></h5>