2013-11-08 1 views
1

Я был удивлен, обнаружив, что поиск JQuery (...) не соответствует объектам в соответствии с их совпадением с CSS документа, а скорее соответствует их «поддереву», Соответствие CSS. Другими словами, если какая-либо часть селектора связана с узлом контекста или его предками при выполнении поиска (...), совпадение не выполняется.Как предотвратить JQuery find() от игнорирования соответствия css контейнера

Кто-нибудь знает эффективное обходное решение, которое позволяет мне использовать те же CSS-идентификаторы на уровне документа (включая совпадения контекста и его предков), что означает, что один и тот же селектор может найти элементы-потомки независимо от того, откуда начинается поиск?

Например, если у вас есть следующее содержание ...

<div class="slide special"> 
<ul> 
    <li>Parent of this text should be selected</li> 
</ul> 
</div> 

... и попытаться найти LI следующим образом ...

var selector = ".special li"; 
var message = ""; 
message += "Global search finds" + $(selector).size() + "\n"; 
$(".slide").each(function(){ 
    message += "Local search finds" + $(this).find(selector).size() + "\n"; 
}); 
alert(message); 

... локальный поиск имеет нулевые совпадения, поскольку привязка для CSS .special - это сам контекстный элемент.

Для библиотеки презентаций слайдов, над которыми я работаю, жизнь для пользователей ниже по течению может быть проще, если они могут использовать одни и те же глобальные идентификаторы для стилей CSS и для связывания поведения JavaScript. Наиболее естественная стратегия CSS заключается в том, что для слайд-контейнеров данного типа есть селектор css, который влияет на стиль и поведение патронов и изображений внутри, но, похоже, я не могу использовать JQuery find (...) для этой работы.

Я думаю, что было бы расточительно и интенсивно находить все совпадающие элементы по всему миру, а затем искать всех своих предков для предполагаемого контекстного элемента, и я предполагаю, что есть какой-то способ JQuery.

Есть ли способ, которым можно использовать селектор уровня документа даже в пределах find(), или обходной путь, который имеет такой же эффект без действительно неприятной и неэффективной итерации?

+2

Проблема в том, что вы находите элементы с классом 'slide', а затем просматриваете * внутри * их для элементов с классом' special'. Я не уверен, чего вы пытаетесь достичь здесь. – Archer

+0

В «локальных поисках поиска» не будет $ (this) .children ('li') для этого? – danielcorreia

+1

CSS будет делать то же самое, что и ваш код. То, что вы ищете в своем коде, это '.slide .special li', но то, что находится в разметке, на самом деле является' .slide.special li' (обратите внимание на нехватку пространства между двумя классами, что очень важно в этот случай.) – Archer

ответ

-1

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

var selector = ".special li"; 
var message = ""; 
message += "Global search finds" + $(selector).size() + "\n"; 
$(".slide").each(function(){ 
    var $wrap = $(this).wrap("<div/>").parent(); 
    message += "Local search finds" + $wrap.find(selector).size() + "\n"; 
}); 
alert(message); 

Проблема заключается в том, что вы ищете внутри div.slide для элементов с классом special, но Арен» t любой. Найти только запросы дочерних элементов. Приведенный выше код будет обертывать выбранный div в другой div и искать внутри него.

Буду честным, я не уверен, в чем дело, но я думаю, что это решит ваш вопрос.

Working jsfiddle example...

+0

Я согласен с тем, что вы можете видеть, что я пытаюсь сделать как «проблема», и что я делаю неправильно. Тем не менее, ограничение, над которым я работаю, требует однородного селектора, используемого как CSS (который управляет стилем), так и JQuery (который связывает поведение), поэтому мне нужно удержать любые специальные исправления, характерные для этой индивидуальной иерархии. –

0

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

var newsetq = matchq.find(selector); 

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

var newsetq = $(selector).filter(function(){ 
    return $(this).parents().addBack().is(matchq); 
}); 

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

0

Я столкнулся с тем же вопросом и подумал, что сделаю что-нибудь с closest. Адаптация моего решения конкретного случая под руку здесь, это будет выглядеть следующим образом:

var newsetq = $(selector).filter(function(){ 
    return $(this).closest(matchq).length; 
}); 

closest call приведет к непустому множеству, если this соответствует matchq. Это должно быть несколько быстрее, чем при использовании parents, потому что closest останавливает движение по дереву DOM, как только будет найдено совпадение, тогда как parents должно пройти все дерево DOM каждый раз.

addBack не нужен здесь, потому что closest вызов начинается с DOM-элементов в объекте JQuery, на котором он называется, прежде чем перейти к родителям.