Проверьте, есть ли элемент до или после другого элемента в jQuery
Предположим, что у меня есть эта разметка
<h3 id="first">First</h3>
<p>Hi</p>
<p>Hello</p>
<h3 id="second">Second</h3>
<p>Bye</p>
<p>Goodbye</p>
Как я могу программно проверить, есть ли элемент, например один из p
s, после h3
и перед вторым h3
, с jQuery?
Я пытаюсь сделать что-то вроде этого:
$(p).each(function(){
if($(this).isAfter("#first") && $(this).isBefore("#second")) {
// do stuff
}
});
Ответы
Ответ 1
Ракетное решение отлично работает, если sel
является реальным селектором, если вы передаете объект jquery, но он не будет работать.
Если вы хотите, чтобы плагин работал как с селекторами, так и с объектами jquery, используйте вместо меня только немного измененную версию:
(function($) {
$.fn.isAfter = function(sel){
return this.prevAll().filter(sel).length !== 0;
};
$.fn.isBefore= function(sel){
return this.nextAll().filter(sel).length !== 0;
};
})(jQuery);
Kudos to Rocket для оригинального решения.
Ответ 2
Чтобы узнать, является ли элемент за другим, вы можете использовать prev()
или prevAll()
, чтобы получить предыдущий элемент и посмотреть, совпадает ли он.
И чтобы увидеть, есть ли элемент перед другим, вы можете использовать next()
или nextAll()
, чтобы получить следующий элемент и посмотреть, совпадает ли он.
$.fn.isAfter = function(sel){
return this.prevAll(sel).length !== 0;
}
$.fn.isBefore= function(sel){
return this.nextAll(sel).length !== 0;
}
DEMO: http://jsfiddle.net/bk4k7/
Ответ 3
Вы можете использовать функцию index()
:
$('p').each(function(){
var index = $(this).index();
if(index > $("#first").index() && index < $("#second").index()) {
// do stuff
}
});
Ответ 4
Вот fiddle
$('p').each(function() {
previousH3 = $(this).prevAll('h3');
nextH3 = $(this).nextAll('h3');
if (previousH3.length > 0 && nextH3.length > 0) {
$(this).css('color', 'red')
}
});
Ответ 5
Я реализовал общую функцию isAfter
, которая рассматривает глубину и дерево DOM и может правильно определить, находится ли a
после b
даже если они находятся в 2 разных поддеревьях:
<div>
<div>
<p class="first">I come first</p>
</div>
</div>
<div>
<div>
<p class="second">I come second</p>
</div>
</div>
Вы можете найти его в моем GitHub Repository. Буду признателен за ваш отзыв о коде
Ответ 6
Ответ:
$.fn.isAfter = function(sel){
return this.prevAll(sel).length !== 0;
}
$.fn.isBefore= function(sel){
return this.nextAll(sel).length !== 0;
}
Выбор всех предыдущих элементов или следующих элементов независимо от селектора (sel), поэтому я сделал следующие изменения, которые выбирают элементы на основе класса:
$.fn.isAfter = function(sel){
sel = "." + sel.attr("class").replace(/ /g, ".");
return this.prevAll(sel).length !== 0;
}
$.fn.isBefore= function(sel){
sel = "." + sel.attr("class").replace(/ /g, ".");
return this.nextAll(sel).length !== 0;
}
Ответ 7
Имея в виду ответ Rocket, я предпочитаю использовать подход .index()
, как показано ниже:
$.fn.isAfter = function(sel){
return $(this).index() > $(sel).index();
};
$.fn.isBefore= function(sel){
return $(this).index() < $(sel).index();
};
Кажется более понятным для чтения/понимания и отлично работает при выборе строк.
Ответ 8
Предыдущие ответы работают хорошо, если рассматриваемые элементы являются родными братьями (что они в исходном вопросе), но более общее решение будет учитывать следующий сценарий:
<div id="top">
<div>
<div>
<h3 id="first">First</h3>
<p>Hi</p>
<p>Hello</p>
</div>
</div>
<div>
<h3 id="second">Second</h3>
<p>Bye</p>
<p>Goodbye</p>
</div>
</div>
Более общее решение будет:
$.extend($.fn, {
isBefore: function(sel, context) {
// Get all element within the context.
var all = $(context || document).find("*");
return all.index(this[0]) < all.index($(sel));
},
isAfter: function(sel, context) {
return !this.isBefore(sel, context);
}
});
Где "context" - это необязательный параметр, который просто ограничивает область поиска для jQuery для повышения производительности. Я не проводил никаких тестов, но "контекст", вероятно, не нужен, поскольку $ ("*"), кажется, выполняется качественно быстро. Также обратите внимание, что index() вернет -1, если любой элемент находится вне контекста.
$("#first").isBefore("#second");
// Gives the same result as
$("#first").isBefore("#second", "#top");
Конечно, все это предполагает, что под "до" и "после" вы подразумеваете их порядок в модели документа. Если вас беспокоит их относительное положение на дисплее, вы можете проверить, отображают ли координаты отображения элементов относительно документа, поскольку "относительные", "фиксированные" и "абсолютные" позиции CSS делают все возможное.
Ответ 9
Принятый ответ работает, только если элементы находятся на одном уровне. Один из подходов к решению этой проблемы, если вы хотите определить, какой элемент находится первым, независимо от уровня:
- Установите временный атрибут для каждого элемента с одинаковым значением
- Используйте селектор jquery, чтобы найти первый элемент со значением этого атрибута