Как найти всех братьев и сестер выбранного объекта
Каков идеальный способ найти все последующие и предыдущие записи в javascript. Я пробовал несколько способов, но не получал точного решения. если какой-либо элемент выбран, мне нужно получить длину всех следующих братьев и сестер, исключая пробел, любые пробелы или разрывы строк
Также я не хочу использовать jquery для этого, я специально смотрю что-то из java script
Прошу совета
Ответы
Ответ 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;
}
}