Подтвердить что ты не робот

Проверьте, есть ли элемент до или после другого элемента в 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
   }
});
4b9b3361

Ответ 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

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

  1. Установите временный атрибут для каждого элемента с одинаковым значением
  2. Используйте селектор jquery, чтобы найти первый элемент со значением этого атрибута