Еще один динамический селектор jquery - PullRequest
0 голосов
/ 20 августа 2010

Я только что задал вопрос о выборе всех идентификаторов в форме id_*, где * - любая строка, а id - это идентификатор элемента. Я получил отличное рабочее решение:

$("*[id^=" + id + "_]").each(function() {... // id is the element name

Мне нужно сделать следующий шаг: Все мои идентификаторы будут иметь вид: a_b_c ..., где a b и c - строки произвольности (которые НЕ содержат ''). Итак, теперь вместо того, чтобы выбирать все элементы формы id_*, где * может быть a_b_c ..., мне нужно выбрать только 1 уровень глубины: все элементы формы id_a. Другими словами, он останавливается на следующем «». Это возможно?

Как пример:

Если мой идентификатор: first И существуют идентификаторы: first_second, first_second_third Он выберет только first_second

Ответы [ 5 ]

1 голос
/ 20 августа 2010

Звучит так, будто вы храните слишком много значений в id поля.С HTML5 у нас теперь есть атрибуты data-.

Возможно, вам следует использовать атрибуты data- примерно так, чтобы связать их?

<div id="a">
</div>

<div id="b0" data-parentId='a'>
</div>

<div id="b1" data-parentId='a'>
</div>

<div id="b2" data-parentId='a'>
</div>

<div id="c" data-parentId='b1'>
</div>

Это все равно будет проверено, так каклюбой нестандартный атрибут, начинающийся с data-, будет считаться действительным.

См .: http://ejohn.org/blog/html-5-data-attributes/

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

Что-то подобное выберет всех детей a

var childrenOfA = $("div[data-parentId='a']);
0 голосов
/ 20 августа 2010

Очевидным решением является изменение вашего документа, например, вместо

<div id="a"></div>
<div id="a_b"></div>
<div id="a_b_c"></div>

вы могли бы написать

<div id="a" class="l1"></div>
<div id="a_b" class="l2"></div>
<div id="a_b_c" class="l3"></div>

и затем выберите $('.l2[id^=a_]'). Если это не вариант, вы можете попробовать какую-нибудь схему сита:

var set = $('[id^='+id+'_]'), i = 0;
while (i < set.length) {
    var e = set.eq(i);
    if (e.attr('id').substr(id.length+1).match('_')) {
        set = set.not(e);
    } else {
        i++;
    }
    set = set.not($('[id^='+e.attr('id')+'_]'));
}

(я не проверял, поэтому могут быть ошибки, и я не уверен, что not - это та, которая вычитает из результирующего набора, но вы поняли.)

Это зависит от структуры документа и браузера, будет ли это на самом деле быстрее, чем наивный смысл простого обхода во время установки и пропуска всего с двумя _ в идентификаторе. (Большое количество ветвей на узел помогает, и, вероятно, это будет быстрее в браузерах, которые имеют собственную реализацию префикса CSS3, который может вызывать jQuery.)

обновление: исправлено несколько ошибок. Логика может меняться в зависимости от вашей структуры, например, самый внутренний, если ветвь не нужна, если foo_bar всегда предшествует foo_bar_baz.

0 голосов
/ 20 августа 2010

Это не дает полного решения, но вы можете попробовать селектор префикса атрибута или атрибут начинается с селектора

Это позволит вам выбрать любого потомка элемента:

$("[id^='a_b_']").each(....

Подумает, как убрать внуков и т. Д., Но это может помочь вам начать.

EDIT

Я только что обнаружил, что аналогичный вопрос был задан в отношении символов подстановки jQuery - похоже, он будет делать то, что вам нужно.

0 голосов
/ 20 августа 2010

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

<div id="a">
    <div id="a_b">
        <div id="a_b_c">
        </div>
    </div>
</div>

Почему бы вам просто не сделать что-то в этом духе ...

<div id="a">
    <div class="b">
        <div class="c">
        </div>
    </div>
</div>

Итак, если бы я просто хотел #a .bЯ бы сделал:

$("#a .b").not("#a .c").show();  

Делает это немного более семантическим и читабельным.Я понимаю, что вы пытаетесь сделать?Возможно, нужно пролить немного света на то, что именно вы делаете

0 голосов
/ 20 августа 2010

То, что я в итоге сделал (и я открыт для более быстрых реализаций):

$("*[id^=" + id + "_]").each(function() {
   //here I simply split the id and test the size of the array
   //if its too large (i.e. too deep in the tree), I return true (to continue
   //  to the next iteration):

   var row = $(this);
   var split = row.attr('id').split("_");

   if(split.length > SOME_PREDETERMINED_VAL)
      return true;

   //code here
});

Я не совсем доволен этим, так как он все равно пересекает все элементы (или все равно сделает это независимо от того,фильтра в функции each () ??).

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