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

Как найти всех братьев и сестер выбранного объекта

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

Также я не хочу использовать jquery для этого, я специально смотрю что-то из java script

Прошу совета

4b9b3361

Ответ 1

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

Если нет, понадобятся корректировки.

var result = [],
    node = this.parentNode.firstChild;

while ( node ) {
    if ( node !== this && node.nodeType === Node.ELEMENT_NODE ) 
      result.push( node );
    node = node.nextElementSibling || node.nextSibling;
}

// result will contain all type 1 siblings of "this"

Ответ 2

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

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

Рабочий пример

получить всех следующих братьев и сестер

//this will start from the current element and get all of the next siblings

function getNextSiblings(elem, filter) {
    var sibs = [];
    while (elem = elem.nextSibling) {
        if (elem.nodeType === 3) continue; // text node
        if (!filter || filter(elem)) sibs.push(elem);
    }
    return sibs;
}

получить всех предыдущих братьев и сестер

//this will start from the current element and get all the previous siblings

function getPreviousSiblings(elem, filter) {
    var sibs = [];
    while (elem = elem.previousSibling) {
        if (elem.nodeType === 3) continue; // text node
        if (!filter || filter(elem)) sibs.push(elem);
    }
    return sibs;
}

получить всех братьев и сестер

//this will start from the first child of the current element parent and get all the siblings

function getAllSiblings(elem, filter) {
    var sibs = [];
    elem = elem.parentNode.firstChild;
    do {
        if (elem.nodeType === 3) continue; // text node
        if (!filter || filter(elem)) sibs.push(elem);
    } while (elem = elem.nextSibling)
    return sibs;
}

пример фильтра для применения к вышеперечисленным функциям

// Example filter only counts divs and spans but could be made more complex
function exampleFilter(elem) {
    switch (elem.nodeName.toUpperCase()) {
        case 'DIV':
            return true;
        case 'SPAN':
            return true;
        default:
            return false;
    }
}

HTML и результат тестирования

HTML

<div id='test'>
    <div id='test2'>asdf</div>
    <br /> sdf
    <div>asdfasdf<span>asdf</span></div>
    <div>a</div>
    <span>a</span>
    <br />
    <div>d</div>
    <hr/>
</div>

JavaScript

var elem;
elem = document.getElementById('test2');

//with filter alerts 4
alert( getNextSiblings( elem, exampleFilter ).length );

// no filter, alerts 7
elem = document.getElementById('test2');// put elem back to what it was
alert( getNextSiblings( elem ).length );

// alerts 0
elem = document.getElementById('test2');// put elem back to what it was
alert( getPreviousSiblings( elem, exampleFilter ).length );

// alerts 5
elem = document.getElementById('test2');// put elem back to what it was
alert( getAllSiblings( elem, exampleFilter ).length );

Ответ 3

Вот очень короткий и простой способ сделать это с ES6:

function getAllSiblings(element, parent) {
        const children = [...parent.children];
        return children.filter(child => child !== element);
    }

Это вернет все дочерние элементы родительского узла, которые не являются элементом.

Ответ 4

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

Ответ 5

Это обновление для ответа @subhaze.

Этот код использует метод matches DOM, который поддерживается в современные браузеры:

Демо

function matches(elem, filter) {
  if (elem && elem.nodeType === 1) {
    if (filter) {
      return elem.matches(filter);
    }
    return true;
  }
  return false;
}

// this will start from the current element and get all of
// the next siblings
function getNextSiblings(elem, filter) {
  var sibs = [];
  while (elem = elem.nextSibling) {
    if (matches(elem, filter)) {
      sibs.push(elem);
    }
  }
  return sibs;
}

// this will start from the current element and get all the
// previous siblings
function getPreviousSiblings(elem, filter) {
  var sibs = [];
  while (elem = elem.previousSibling) {
    if (matches(elem, filter)) {
      sibs.push(elem);
    }
  }
  return sibs;
}

// this will start from the first child of the current element's
// parent and get all the siblings
function getAllSiblings(elem, filter) {
  var sibs = [];
  elem = elem.parentNode.firstChild;
  while (elem = elem.nextSibling) {
    if (matches(elem, filter)) {
      sibs.push(elem);
    }
  } 
  return sibs;
}

Используйте эти функции следующим образом:

var elem = document.querySelector('#test');

// find all the "div" and "span" siblings
var after = getNextSiblings(elem, 'div, span');

// find previous siblings with ".list-item" class
var index = getPreviousSiblings(elem, '.list-item');

// get all siblings with a title attribute
var allSibs = getAllSiblings(elem, '[title]');

Ответ 6

вернуться к 2017 году:
Может быть, есть лучший ответ, но это хорошо и немного чище.

function sibiling(dom, query) {
   var doms = dom.parentElement.querySelectorAll(query);
   return [].slice.call(doms).filter( d => d != dom);
}

Ответ 7

Этот ответ был ранее опубликован здесь в ответ на аналогичный вопрос.

Есть несколько способов сделать это.

Любой из следующих действий должен сделать трюк.

// METHOD A (ARRAY.FILTER, STRING.INDEXOF)
var siblings = function(node, children) {
    siblingList = children.filter(function(val) {
        return [node].indexOf(val) != -1;
    });
    return siblingList;
}

// METHOD B (FOR LOOP, IF STATEMENT, ARRAY.PUSH)
var siblings = function(node, children) {
    var siblingList = [];
    for (var n = children.length - 1; n >= 0; n--) {
        if (children[n] != node) {
            siblingList.push(children[n]);
        }  
    }
    return siblingList;
}

// METHOD C (STRING.INDEXOF, ARRAY.SPLICE)
var siblings = function(node, children) {
   siblingList = children;
   index = siblingList.indexOf(node);
   if(index != -1) {
       siblingList.splice(index, 1);
   }
   return siblingList;
}

FYI: Кодовая база jQuery - отличный ресурс для наблюдения Javascript класса A.

Вот отличный инструмент, который очень хорошо раскрывает кодовую базу jQuery. http://james.padolsey.com/jquery/

Ответ 8

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

const getPreviousAll = element => {
  const previousAllFound = [];
  const getPrevious = element => {
    if (element !== null) {
      previousAllFound.push(element);
      const previousFound = element.previousElementSibling;
      if (previousFound !== null) {
        getPrevious(previousFound);
      }
    }
  };
  getPrevious(element.previousElementSibling);
  return previousAllFound;
};
const getNextAll = element => {
  const target = element;
  const nextAllFound = [];
  const getAll = element => {
    if (element !== null) {
      nextAllFound.push(element);
      const nextFound = element.nextElementSibling;
      if (nextFound !== null) {
        getAll(nextFound);
      }
    }
  };
  getAll(element.nextElementSibling);
  return nextAllFound;
};

Вам просто нужно вызвать эту функцию с узлом, который вы можете получить с помощью getElementById.

Ответ 9

  Все предыдущие братья и сестры

// jQuery (optional filter selector)
$el.prevAll($filter);

// Native (optional filter function)
function getPreviousSiblings(elem, filter) {
  var sibs = [];
  while (elem = elem.previousSibling) {
      if (elem.nodeType === 3) continue; // ignore text nodes
      if (!filter || filter(elem)) sibs.push(elem);
  }
  return sibs;
}

Все ближайшие братья и сестры

// jQuery (optional selector filter)
$el.nextAll($filter);

// Native (optional filter function)
function getNextSiblings(elem, filter) {
        var sibs = [];
        var nextElem = elem.parentNode.firstChild;
        do {
            if (nextElem.nodeType === 3) continue; // ignore text nodes
            if (nextElem === elem) continue; // ignore elem of target
            if (nextElem === elem.nextElementSibling) {
                if (!filter || filter(elem)) {
                    sibs.push(nextElem);
                    elem = nextElem;
                }
            }
        } while(nextElem = nextElem.nextSibling)
        return sibs;
    }

Пример функции фильтра:

function exampleFilter(elem) {
  switch (elem.nodeName.toUpperCase()) {
    case 'DIV':
      return true;
    case 'SPAN':
      return true;
    default:
      return false;
  }
}