Обход вложенного списка html с помощью javascript
У меня есть список HTML (<ul>
, <li>
, и т.д.) страниц, с несколькими элементами на различной глубине. Я пытаюсь написать некоторый код, чтобы обойти этот список по одному элементу за раз. Таким образом, кнопка "next" возвращает идентификатор следующего элемента <li>
, который может быть прямым родственником текущего элемента, или он будет находиться в дочернем элементе <ul>
, или он может быть в родительском элементе <ul>
. Аналогично, кнопка "prev" будет делать то же самое, но в обратном порядке.
Вот несколько примеров html:
<ul>
<li id="post_item_1"><a href="#post1">Vestibulum ultrices, ante non tincidunt molestie, purus enim varius urna, nec bibendum...</a>
<ul>
<li id="post_item_26"><a href="#post26">This planet has — or rather had — a problem, which was this: most of...</a>
<ul>
<li id="post_item_27"><a href="#post27">A towel, it says, is about the most massively useful thing an interstellar hitch...</a>
</li>
</ul>
</li>
</ul>
</li>
<li id="post_item_2"><a href="#post2">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin nec velit augue,...</a>
<ul>
<li id="post_item_58"><a href="#post58">Reply to first post, with an edit</a>
</li>
<li id="post_item_59"><a href="#post59">Another reply to first post, made after the first reply</a>
</li>
</ul>
</li>
<li id="post_item_4"><a href="#post4">Phasellus vitae est tellus, vel aliquam lectus. Cras augue tellus, pulvinar a blandit...</a>
<ul>
<li id="post_item_60"><a href="#post60">Reply to second post</a>
</li>
</ul>
</li>
<li id="post_item_3"><a href="#post3">Pellentesque consequat urna mauris, luctus adipiscing enim. Sed quis lectus vel...</a>
</li>
<li id="post_item_28"><a href="#post28">"The Babel fish" said The Hitchhiker's Guide to the Galaxy quietly, "is small, yellow...</a>
</li>
<li id="post_item_61"><a href="#post61">Hello there, it is very worrying</a>
<ul>
<li id="post_item_62"><a href="#post62">Don't be scared, or scarred, or sacred, or Skesis!</a>
</li>
</ul>
</li>
<li id="post_item_67"><a href="#post67">Well, to be fair, at the end of the day, when all is said and done, I'd like to...</a>
</li>
</ul>
Я играл с jquery в течение нескольких часов, и это все, что у меня есть:
if (!node) {
// start with the selected node
node = $('#content #postNavigator ul li.selected')
}
if ( $(node).has('ul').length ) {
// has child <ul>
nextNode = $($(node).children()[1]).children()[0];
}
else {
// has a sibling
if ($(node).next('li').length) {
nextNode = $(node).next('li');
}
else {
// recursion needed here - this code will return parent, but only when 1 level deep.
if ($(node).parent().parent().next('li').length) {
nextNode = $(node).parent().parent().next('li');
}
else {
return false;
}
}
}
Вышеописанное возвращает следующий узел или дочерний узел, если он есть, и возвращает родительский узел, если нет больше братьев или сестер или детей, но только один уровень глубиной. HTML-список может иметь неограниченную глубину, поэтому может потребоваться какая-то рекурсия? Это все, на что способны мои навыки. Я даже не начинал думать о ссылке "prev", чтобы работать над этим списком в так же, но в обратном порядке.
Я задал тот же вопрос на devshed (несколько недель назад), но не получил ответа.Спасибо всем за ваши ответы.
Ниндзя, я осуществил ваш с некоторым успехом. Теперь я могу перемещаться вверх и вниз по вложенному списку очень хорошо.
Еще один вопрос, если вы будете так любезны: мне нужна способность начать "положение" в точке внутри дерева. Пользователи могут выбрать узел в дереве с помощью хэша (например, #post9) - они могут щелкнуть узел в любом месте списка, чтобы выбрать его, или они могут добавить в закладки url-адрес, который будет включать собственный хэш этого узла.Итак, мой следующий вопрос: как бы я нашел узел в дереве и получил его позицию, используя хэш в URL? Хэш в URL-адресе коррелирует с идентификатором узла li .
3 ответа:
Поскольку вы уже используете jQuery, вы можете также воспользоваться его встроенными механизмами обхода DOM. В этом случае вы будете заботиться в основном о
$().find
и$().eq
.$().найти
JQuery действительно может найти каждый соответствующий элемент, который существует ниже уровня любого другого селектора. Этот единственный метод сделает за вас большую часть вашей работы.
// Returns a jQuery object containing every 'li' on the page var items = $('body').find('li');
$().eq
На самом деле у вас есть несколько вариантов доступа к этим отдельным
li
теперь элементы. jQuery-это Массивоподобная структура, которая означает, что вы можете обращаться к каждому элементу по его индексу. но jQuery также имеет встроенный метод для получения отдельных элементов из коллекции, и они также будут возвращены в виде объектов jQuery.// Good: Returns the first element from the jQuery collection as a JS DOMElement items[0]; // Better: Returns the first element from the jQuery collection as a jQuery collection items.eq(0);
Собирая его вместе
Теперь, когда у вас есть инструменты, вам просто нужно применить немного логики, чтобы перейти от одного элемента к следующему в списке. Вот все, что вам действительно нужно; я также скопировал вашу разметку в проект jsFiddle и добавил немного функциональности, чтобы показать вам, как он работает: http://jsfiddle.net/ninjascript/Kt8f8/.var items = $('body').find('li'); var length = items.length; var position = -1; function next() { position = (position + 1 < length) ? position + 1 : 0; return items.eq(position); }
Удачи!
Я верю, что это сработает:
function nextNode(selectedNode) { var nextNode = selectedNode.next("li"); if (nextNode.length) { return nextNode; } return nextNode.closest("li").next(); }
Что это делает, так это берет выбранный узел и возвращает следующий узел, если он есть. Если нет, он ищет ближайший Родительский тег li и получает от него следующий узел.
Если вы dnt хотите использовать внешние библиотеки, то вам нужно использовать комбинацию методы документов javascript
И
Удачи!