Jquery - найти следующий элемент input:text после известного элемента

У меня есть идентификатор для <tr id="tagTR"> Учитывая вышеизложенное, можно ли найти следующий элемент input:text независимо от любой другой разметки между ними. Есть ли селектор jQuery, который я могу использовать для этого сценария?

Например :

<tr id="tagTR"> 
</tr>
<tr id="tagRed"> 

  <td> </td>
</tr>
<div>
 <tr>
   <td>
     <input> // This is what I want to get to. 
   </td>
 </tr>
</div>

person user1006072    schedule 17.01.2012    source источник
comment
Пожалуйста, опубликуйте свою фактическую разметку. У вас есть <tr> элементов с <div> родительскими и одноуровневыми элементами, что является недопустимым HTML.   -  person Frédéric Hamidi    schedule 18.01.2012
comment
Вам нужно использовать nextAll() для поиска всех братьев и сестер относительно известного элемента маркера, и если то, что вы ищете, не найдено, возьмите список .parents() известного элемента и переберите каждого брата и сестры каждого родителя, чтобы найти рассматриваемый элемент, в основном вызов nextAll() для каждого родителя вашего известного элемента.   -  person Jeff Wilbert    schedule 18.01.2012
comment
@Frederic - Вы правы, это недопустимый HTML, но это был просто пример кода, который я создал на лету, вопрос был больше о поиске следующего элемента ввода. Спасибо, в любом случае.   -  person user1006072    schedule 18.01.2012
comment
@JeffWilbert Спасибо, Джефф, это должно помочь.   -  person user1006072    schedule 18.01.2012


Ответы (5)


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

http://jsfiddle.net/GesSj/1

//assume you know where you are starting from
var $startElement = $('#foo');

//get all text inputs
var $inputs = $('input[type=text]');

//search inputs for one that comes after starting element
for (var i = 0; i < $inputs.length; i++) {
    if (isAfter($inputs[i], $startElement)) {
        var nextInput = $inputs[i];
        alert($(nextInput).val());
    }
}

//is element before or after
function isAfter(elA, elB) {
    return ($('*').index($(elA).last()) > $('*').index($(elB).first()));
}
person mrtsherman    schedule 17.01.2012
comment
Большое спасибо mrtsherman. Вы абсолютно правы, это было моим намерением, и именно так я хотел, чтобы читатель интерпретировал вопрос. Ваши решения интересны, но мне было интересно, есть ли для него простой селектор Jquery. - person user1006072; 18.01.2012
comment
@ user1006072 - к сожалению, нет. Это довольно необычный вопрос, потому что обычно есть НЕКОТОРАЯ структура, на которую можно положиться. Затем вы должны использовать next, nextAll, filter или find. - person mrtsherman; 18.01.2012
comment
Я опубликовал другое решение, основанное на вашем. (указывая, потому что я только что понял, что вы, возможно, не получили никаких уведомлений о моем упоминании там) - person cregox; 21.04.2015

Проверьте это: переместил это в более полный вопрос и ответ

На основе отличного ответа от @mrtsherman, я написал более полное решение:

(function( $ ){
 $.fn.findNext = function(sel) {
   var $result = $(sel).first();
   if ($result.length <= 0) {
     return $result;
   }
   $result = [];
   var thisIndex = $('*').index($(this));
   var selIndex = Number.MAX_VALUE; // Number.MAX_SAFE_INTEGER is not yet fully supported
   $(sel).each(function(i,val){
     var valIndex = $('*').index($(val));
     if (thisIndex < valIndex && valIndex < selIndex) {
       selIndex = valIndex;
       $result = $(val);
     }
   });
   return $result;
 }; 
})( jQuery );

Затем вы можете использовать его следующим образом:

$('#tagTR').findNext('input');

Я бы отправил PR для этого в jQuery lib, если бы знал свой код был должным образом оптимизирован, и если г-н Т. Шерман не возражал, это означает, что я думаю, что это должен быть основной метод в jQuery! :П

person cregox    schedule 16.03.2015
comment
лол, спасибо @vincent, но почему люди до сих пор используют jQuery? так как я долгое время не программировал достаточно глубоко (и я слишком ленив сейчас для stfw), я, честно говоря, понятия не имею! ???? - person cregox; 03.10.2020

@Cawas - хорошее решение, но советую не злоупотреблять, ибо $('*') дорого ;-)

Несмотря на это, я расширил его для своих нужд:

(function( $ ){
     $.fn.findNextOverall = function(sel, returnItselfIfMatched) {

       if(returnItselfIfMatched && $(this).is(sel)) return $(this);

       var $result = $(sel).first();
       if ($result.length <= 0) {
         return $result;
       }
       $result = [];
       var thisIndex = $('*').index($(this));
       var selIndex = Number.MAX_SAFE_INTEGER;
       $(sel).each(function(i,val){
         var valIndex = $('*').index($(val));
         if (thisIndex < valIndex && valIndex < selIndex) {
           selIndex = valIndex;
           $result = $(val);
         }
       });
       return $result;
     }; 
    })( jQuery );

Итак, если returnItselfIfMatched установлен true, он возвращает себя, если он соответствует самому селектору. Полезно, если не знаешь, какой элемент вызывает и ищешь именно себя.

person Andre Lehnert    schedule 18.04.2015
comment
Да, интересно, можно ли как-то сделать это без $('*')... Итак, вы в основном добавили туда только очень конкретный if, что является довольно узким вариантом использования. Я бы сказал, что это было бы лучше в качестве расширенной функции в вашем коде или прямо в самом коде. - person cregox; 21.04.2015
comment
Я использую его в больших формах, где мне нужно знать, какой элемент имеет фокус, чтобы применить больше элементов на основе сочетаний клавиш. То, что пользователь часто делает эти ярлыки, в то время как фокус уже находится в самой цели. Так что проще поместить его в плагин, чтобы получить меньше строк кода. Но независимо от этого, почему бы не сделать это утверждение if. Это уменьшает обход DOM, и в этом случае вы не получаете нулевого возврата. $('*') можно было бы оптимизировать рекурсивным переходом через следующий более высокий уровень возврата при сопоставлении с первым элементом. Но для меня в моем проекте все в порядке. Привет, Андре. - person Andre Lehnert; 21.04.2015
comment
Теперь я не уверен, что универсальный селектор имеет какое-либо влияние на производительность, при использовании сам по себе . Вы случайно не знаете лучше? - person cregox; 07.05.2015

У вас не может быть тега div между TR's. Это недопустимая разметка.

Чтобы найти элемент input из указанного tr, вы можете попробовать это.

$('#tagTR').nextAll().filter(function(){
    return $(this).find('input:text').length > 1;
}).find('input');
person ShankarSangoli    schedule 17.01.2012
comment
Это будет искать только родного брата относительно тега для ввода, основываясь на вопросе ОП, который он хочет найти следующий ввод относительно тега, будь то в братьях и сестрах, родителя или его брата, вам просто нужно добавить цикл всех родителей тега с вызовом nextAll(). - person Jeff Wilbert; 18.01.2012
comment
В этом случае мы не знаем, на что хочет смотреть OP родительского уровня. Я думаю, что OP хочет посмотреть во всех других строках. - person ShankarSangoli; 18.01.2012
comment
Не будет уровня, на котором будут все родители, пока не будет найден следующий вход или пока вы не достигнете начального родительского HTML, вам нужно использовать .parents() для перебора всех родителей узла TR и с каждым родителем использовать .nextAll() для поиск всех его братьев и сестер для ввода. Я только что понял, что даже тогда это не сработает именно потому, что родительский узел может иметь входные данные, которые находятся перед тем, где находится элемент тега. - person Jeff Wilbert; 18.01.2012
comment
Это имеет смысл, но все зависит от знания OP разметки. Мы можем сначала посмотреть на братьев и сестер, если они отсутствуют, затем посмотреть на один уровень вверх и продолжать двигаться на один уровень вверх, пока не найдем его. - person ShankarSangoli; 18.01.2012
comment
Также следует помнить, что при использовании .parents() и .nextAll() для поиска входных данных это, например, jsfiddle.net/WNsaD посмотрите на разметку HTML. Вы должны убедиться, что найденный ввод находится впереди/перед элементом маркера, а не за ним. - person Jeff Wilbert; 18.01.2012
comment
Хорошая дискуссия - спасибо всем за участие. Позвольте мне попытаться рассказать как можно больше индивидуально @ShankarSangoli - Большое спасибо. Я как бы понимаю, что вы пытаетесь сделать, но не уверен, почему .length › 1 ? - person user1006072; 18.01.2012
comment
@JeffWilbert - Вы правы в том, что говорите, но я намеревался начать с элемента, для которого у меня есть идентификатор, и предположить, что у меня мало информации о дальнейшей разметке, мне просто нужно перейти к следующему вводу. :текстовый элемент. Хотя спасибо за предложения и комментарии.. - person user1006072; 18.01.2012

Вы можете использовать «далее»:

$("#tagTR").next("input")
person Troy Barlow    schedule 17.01.2012
comment
next просматривает только непосредственно следующего брата и возвращает его, если он соответствует селектору. - person James Allardice; 18.01.2012