Вот то, что я придумал на лету:
Во-первых, я бы внес небольшую поправку в ваш HTML (я не уверен, что у вас есть на самом деле ... это может показать, как вам нравится, но конструктивно это вызовет проблемы). Будет трудно установить значение "li", если оно имеет значение И вложенный список. Если вы сбросите innerText или внутренний Html, вы полностью перезапишите остальную часть HTML в этом теге, что означает, что вы потеряете вложенный список. Вы можете обойти это, но зачем беспокоиться, просто закройте эти теги предсказуемо.
(заметьте, я не думаю, что другие ответы решают эту проблему).
Итак, сначала я сделаю это, обратите внимание, как я закрываю "li" для Cat, Dog и Fi sh:
<ul class='root'>
<li>Cat</li>
<ul>
<li>Eats1</li>
<li>Sleeps</li>
<li>Snuggles</li>
<li>Plays</li>
<li>Meows</li>
</ul>
<li>Dog</li>
<ul>
<li>Eats2</li>
<li>Sleeps</li>
<li>Snuggles</li>
<li>Plays</li>
<li>Barks</li>
</ul>
<li>Fish</li>
<ul>
<li>Eats3</li>
<li>Sleeps</li>
<li>Swims</li>
<li>Plays</li>
<li>Swims</li>
</ul>
</ul>
Теперь вы можете выбирать элементы и устанавливать значения очень просто (а HTML - это звук); Селекторы здесь в основном говорят: «Дайте мне детей li и ul, которые являются ТОЛЬКО прямыми потомками того элемента, с которым я в данный момент работаю» (иначе вы получите их все, независимо от того, насколько глубоко они вложены, чего вы не хотите).
Этот код дает вам желаемый результат, работая рекурсивно над вложенными коллекциями "li" и "ul", обратите внимание, что он также работает с коллекцией верхнего уровня "li":
const top_layer = document.querySelectorAll ( '.root' );
const the_new_val = 'THE NEW VAL';
function setProps ( elems, level ) {
Array.from ( elems ).forEach ( x => {
const li = x.querySelectorAll ( ':scope > li' );
const ul = x.querySelectorAll ( ':scope > ul' );
if ( Array.from ( li ).length >= level ) {
li [ level ].innerText = the_new_val;
setProps ( li [ level ].children, level );
}
if ( Array.from ( ul ).length ) {
setProps ( ul, level );
}
});
}
setProps ( top_layer, 2 );
Да, вы можете работать с «потомками», но поскольку нас непосредственно интересует установка значений «li», которые всегда появляются в тегах «ul», явные селекторы делают более очевидным, что происходит, и игнорируют любые другие потомки, которые могут будьте рядом, не стесняйтесь вносить эти изменения, если хотите.
Отображаемый результат: