Проблема с селектором jquery в иерархическом раскрывающемся/сворачивающемся дереве

Я пытаюсь построить экран, который будет представлять собой иерархический список закладок, сгруппированных по категориям. Категории могут быть расширены/свернуты, чтобы показать или скрыть закладки для этой категории. Прямо сейчас я просто работаю над пользовательским интерфейсом и впервые использую jquery (и мне это нравится).

Методология, которую я использую, похожа на аккордеон, но одновременно может быть открыто более одного раздела, и может быть несколько уровней глубины (аккордеон поддерживает только один уровень). Для каждой категории есть div с изображением папки в нем, который будет отображать или скрывать следующий элемент в DOM, который будет набором закладок (обычно ‹ul›). например:

<div class="categoryLine" id="d4">
    <img class="folder"....>
    Fourth Menu Item
</div>
<ul id="u4">
    <li id="l41">

Я выбираю элемент для закрытия с помощью $(this).parentsUntil('categoryLine').next().toggle(transitionSpeed);, где div вокруг изображения, на которое нажимает пользователь, имеет класс categoryLine, а элемент, который нужно показать/скрыть, — это элемент, следующий за этим div.

Проблема в самой сложной (самой глубокой иерархии) части, скрываются некоторые вещи, которых быть не должно, и по непонятным причинам вновь появляются.

Вы можете увидеть «рабочий» пример здесь. Я дал соответствующие идентификаторы тегов и добавил предупреждение об отладке, чтобы отобразить идентификатор элемента, на который нажали, а также элементы, которые нужно открыть и закрыть (см. исходный код, чтобы увидеть это).

  1. Нажмите на папку «Четвертый пункт меню», чтобы отобразить эту категорию. Вы должны увидеть подпрограммы 1, 2 и 3.
  2. Нажмите на папку для «Четвертого пункта меню, подпункт 1». Вы должны увидеть, что подпункт 1 расширяется, но подпункт 2 полностью исчезает, включая строку категории. Это загадка, которую я пытаюсь разгадать. Нажатие на сабвуфер 1 правильно говорит «Переключение« u411 »из категории« d41 »», но когда исчезает ‹ul› u411, исчезает и весь сабвуфер 2. Точно так же, если я нажму на папку, чтобы развернуть sub2, sub3 исчезнет.

Я готов реализовать это совершенно по-другому (опять же, это мой первый эксперимент с jquery). Я также хотел бы рассмотреть решения, в которых одновременно может быть открыта только одна категория, если она по-прежнему поддерживает иерархию, а не одну глубокую, как аккордеон.

Заранее спасибо.


person dj_segfault    schedule 15.02.2010    source источник


Ответы (1)


jQuery описывает parentsUntil() как:

Описание: Получить предков каждого элемента в текущем наборе совпавших элементов, вплоть до элемента, совпавшего с селектором, но не включая его.

Важно отметить, что вы не выбираете .categoryLine. Хотя кажется, что вы хотите включить его. Должно работать, если вместо этого вы используете closest().

$(this).closest('.categoryLine').next().toggle(transitionSpeed); 

В качестве примечания для дальнейшего использования. ('categoryLine') не является селектором. Как правило, вам нужно включить ., # или тип элемента, например div. Хотя есть и более продвинутые методы. Вы можете прочитать об селекторах jQuery.

person munch    schedule 15.02.2010
comment
На самом деле нет. Сама строка категории НЕ должна исчезать, иначе вы не сможете открыть ее снова. Это любой элемент, который находится после div categoryLine, который должен отображаться и скрываться, и это может быть другой div или ul. Когда страница загружается, отображаются 4 строки категорий. При нажатии на папку строки категории открывается содержимое этой категории (следующий элемент), но строка категории всегда остается видимой. - person dj_segfault; 15.02.2010
comment
Если вы еще раз посмотрите на эту строку, у меня есть файл . (класс) там. Причина, по которой я использовал идентификаторы классов вместо идентификаторов, заключается в том, чтобы уменьшить нагрузку на его настройку. Необходимость придумывать и сопоставлять идентификаторы между строкой категории и контентом требовала гораздо больше работы. Кроме того, пример, который я видел на michaeljacobdavis.com/tutorials/statesavingaccordion.html, работал таким образом. - person dj_segfault; 15.02.2010
comment
Я согласен, что использование класса правильно. Вы правильно все настроили. Однако ваш синтаксис неверен. Правильный синтаксис: parentsUntil('.categoryLine') . позволяет jquery знать, что нужно искать что-то с этим классом. С моим кодом категория не исчезнет. Элемент next() после категории исчезнет, ​​что выглядит так, будто это ul. - person munch; 15.02.2010
comment
Взяв код прямо с вашей страницы и изменив одну строку на то, что у меня там сработало. Вот тестовая страница. Простите битые изображения. jsbin.com/orice - person munch; 15.02.2010
comment
Я понимаю вашу точку зрения, и это была опечатка. Я знаю, что точка нужна. Однако, когда я беру точно такой же код и ставлю там точку, папки никаких не открываются. предупреждение об отладке тоже не работает. В нем говорится о переключении «нуль» из категории «нуль», поэтому с точкой он не находит родителя. См. thekramers.net/tmp/jqueryproblem/accordionfakeiconwithdot.html, который является точно таким же кодом. за исключением точки в параметре parentUntil. Когда я смотрю на пример, для которого вы прислали URL-адрес, я даже не вижу диалогового окна, не говоря уже об открывающихся окнах. - person dj_segfault; 16.02.2010
comment
Мунк, я на самом деле нашел другой способ сделать это, который, кажется, отлично работает. Вместо использования .parentsUntil() я просто использую .parent(), так как div categoryLine всегда будет родителем изображения папки. Например, $(this).parent().next() вместо $(this).parentsUntil(.categoryLine).next() работает отлично. Однако я собираюсь отметить ваш ответ как правильный, потому что вы потратили на него некоторое время и действительно нашли ошибку. Мне было бы любопытно узнать ваше мнение о том, почему исправление селектора на самом деле сломало его еще больше. - person dj_segfault; 16.02.2010
comment
Я не думаю, что это ошибка. parentsUntil выберет всех предков, если селектор отсутствует или если он ничего не возвращает, поэтому любой предок, у которого был элемент next(), был затронут. parent() тоже хорошее решение. Важно то, что вы хотите выбрать ближайшего предка .categoryLine, а затем переключиться на следующего ul. Рад, что это работает. - person munch; 16.02.2010