В целом задача состоит в том, чтобы сделать вывод реактивного оглавления для содержимого WYSIWYG редактора.
В качестве JS-фреймворка я использую React, в качестве редактора - ckeditor. Задача состояла в том, чтобы сделать следующее - при заполнении редактора контентом, заголовки 1-3 уровня парсятся и реактивно выводятся в виде оглавления рядом с окном редактора. При этом пункты в этом оглавлении должны быть кликабельны - по клику должно происходить прокручивание окна редактора до соответствующего заголовка. Имеющиеся плагины позволяют только выводить таблицу с оглавлением, но не делать ее элементы кликабельными.
Задачу я решил, но мне кажется, мой код весьма топорен и плохо масштабируем.
Ссылка на песочницу с примером
Допустим, если условия задачи поменяются и надо будет парсить заголовки 1-6 уровня, то мой код вырастет в 2 раза. Я пытался найти более изящное решение с применением рекурсий в этих моментах:
while (currentEl !== null) {
if (currentEl.tagName === 'H1') {
h1Array.push({
text: currentEl.innerHTML,
h2Array: []
});
i++;
j = 0;
} else if (currentEl.tagName === 'H2') {
h1Array[i-1].h2Array.push({
text: currentEl.innerHTML,
h3Array: []
});
j++;
} else if (currentEl.tagName === 'H3') {
h1Array[i-1].h2Array[j-1].h3Array.push({
text: currentEl.innerHTML
});
}
currentEl = currentEl.nextElementSibling;
}
и
// finding closest h2 tag
let h2El = h1El.nextElementSibling;
let i = 0;
while (i <= +h2Index) {
if (h2El.tagName === 'H2') {
if (i === +h2Index) {
break
} else i++;
}
h2El = h2El.nextElementSibling;
}
// finding h3 tag
let h3El = h2El.nextElementSibling;
let j = 0;
while (j <= +h3Index) {
if (h3El.tagName === 'H3') {
if (j === +h3Index) {
break
} else j++;
}
h3El = h3El.nextElementSibling;
}
но у меня ничего не получилось.