Обход HTML-вложенного списка с использованием JavaScript - PullRequest
2 голосов
/ 13 августа 2011

У меня есть список HTML (<ul>, <li> и т. Д.) Страниц с несколькими элементами на разной глубине.Я пытаюсь написать некоторый код для обхода этого списка по одному элементу за раз.Таким образом, кнопка «Далее» будет возвращать идентификатор следующего элемента <li>, который может быть прямым братом текущего элемента или находиться в дочернем элементе <ul>, или в родительском * 1005.* элемент.Аналогично, кнопка «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 &mdash; or rather had &mdash; 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 ]

2 голосов
/ 13 августа 2011

Поскольку вы уже используете jQuery, вы также можете воспользоваться его встроенными механизмами обхода DOM. В этом случае вы будете заботиться в основном о $().find и $().eq.

$ (). Найти

jQuery может фактически найти каждый соответствующий элемент, который существует ниже уровня любого другого селектора. Этот единственный метод сделает большую часть вашей работы за вас.

// Returns a jQuery object containing every 'li' on the page
var items = $('body').find('li');

$ (). Экв

На самом деле у вас есть несколько вариантов доступа к этим отдельным элементам 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);
}

Удачи!

0 голосов
/ 13 августа 2011

если вы не хотите использовать внешние библиотеки, вам нужно использовать комбинацию методов документа javascript

и

методов элемента dom

Удачи!

0 голосов
/ 13 августа 2011

Я считаю, что это будет работать:

    function nextNode(selectedNode) {
    var nextNode = selectedNode.next("li");
    if (nextNode.length) {
        return nextNode;
    }

    return nextNode.closest("li").next();
}

Для этого нужно взять выбранный узел и вернуть следующий узел, если он есть. Если нет, он ищет ближайший родительский тег li и получает от него следующий узел.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...