Еще один ближайший дочерний поток: поиск ближайшего предка элемента, который соответствует селектору

0

Вот схема HTML-модуля:

.module
  .module-title
  .module-foo
    .module-bar
  .module-children

Модули могут входить друг в друга:

.module
  .module-title
  .module-foo
    .module-bar
  .module-children
    .module
      .module-title
      .module-foo
        .module-bar
      .module-children
        .module
          .module-title
          .module-foo
            .module-bar
          .module-children
        .module
          .module-title
          .module-foo
            .module-bar
          .module-children
  .module
    .module-title
    .module-foo
      .module-bar
    .module-children

У меня есть самый верхний. .module хранится в $module jQuery объекта $module.

Теперь я хотел бы выбрать .module-bar который принадлежит к самому .module-bar модулю, не включая те, которые принадлежат к вложенным модулям.

Проблема в том, что я не хочу жестко задавать иерархию.

E. g. я мог бы сделать это:

$bar = $module.find('> .module-foo > .module-bar');

Или это:

$bar = $module.find('.module-bar').eq(0);

Но структура содержимого модулей подвержена незначительным изменениям. Подэлементы могут отображаться в другом порядке или входить в разные формы. Любая из этих изменений HTML нарушит JS-код, и я хочу, чтобы код был проворным и терпимым к незначительным изменениям структуры HTML.

Вместо этого я хотел бы сделать что-то вроде:

$bar = $module.closestChild('.module-bar');

Я нашел несколько вопросов и решений, которые можно было бы описать как "reverse closest() ". Вот один пример: https://github.com/jstnjns/jquery-nearest/ Но это меня не устраивает, потому что оно предотвращает только перемещение внутри экземпляров цели. И в моем случае целевые элементы не содержат вложенных модулей, поэтому nearest() будет выбирать все экземпляры .module-bar.

Другие решения просто не соответствуют требованиям. Например, qaru.site/questions/760606/... полагается на .first().

  • 0
    Когда вы говорите «дети», вы на самом деле имеете в виду дочерние элементы, как и в .module-foo , или вы имеете в виду только элемент с классом module-children , есть разница.
  • 0
    Хороший улов. Я отредактировал вопрос, чтобы быть более понятным.
Показать ещё 4 комментария
Теги:

3 ответа

1

Таким образом, я сделал крошечный плагин jQuery jquery.closestchild, который шаг за шагом пересекает дерево и не будет идти дальше, как только он найдет совпадение.

Плагин: https://github.com/lolmaus/jquery.closestchild/

Демо: http://lolmaus.github.io/jquery.closestchild/

Здесь выполняется тест производительности против решения adeneo: http://jsperf.com/closestchild#runner. Плагин работает в восемь раз быстрее, и разница должна увеличиваться пропорционально глубине дерева DOM.

1

Вы можете фильтровать родителей

var $bars = $module.find('.module-bar').filter(function() {
                return $(this).closest('.module').get(0) === $module.get(0);
            });

Это исключает любой вложенный вложенный .module-bar чем один .module

FIDDLE

или (делает то же, что и выше внутри, поэтому, вероятно, не более эффективно)

 var $bars = $module.find('.module-bar').not('.module .module .module-bar');

FIDDLE

  • 0
    Это все еще делает предположение об уровне вложенности, хотя.
  • 0
    @FelixKling - Да? Можно проверить количество parents() до $module , но это также делает предположения о вложенности. Не уверен, что я действительно понял это?
Показать ещё 8 комментариев
0
$module.find(':not(.module .module .module-bar)').filter('.module-bar')

Но я предполагаю, что .module-bar будет находиться под основным .module и детьми. .modules будут находиться под основным .module.

http://jsfiddle.net/zsQnH/2/

  • 0
    Вы ссылаетесь на другое решение. Я предполагаю, что ваше решение не удастся для некорневых модулей?
  • 0
    Я исправил скриптовую ссылку. Благодарю. Это не удастся в зависимости от условий. Если он имеет не-root .module как переменную $ module, мое решение не подведет, потому что он использует find . Который работает только с внутренними элементами DOM.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню