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

Получить братьев и сестер в JavaScript, без библиотек

Как я могу искать братьев и сестер "вверх" с помощью JavaScript? В принципе, мне нужна функция prevUntil(), подобная той, что присутствует в jQuery.

У меня есть много элементов <div>, все на одном уровне, например:

<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>

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

Как я могу это сделать, пожалуйста?

4b9b3361

Ответ 1

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

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

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

// 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;
}

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

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

Ответ 2

Пример Использование previousSibling:

    var className = "needle";
    var element = clickedElement;
    while(element.previousSibling && element.previousSibling.className != className) {
       element = element.previousSibling;
    }
    element.previousSibling; // the element or null

Ответ 3

Используйте .children в сочетании с .parentNode. Затем отфильтруйте NodeList после преобразования его в массив: http://jsfiddle.net/pimvdb/DYSAm/.

var div = document.getElementsByTagName('div')[0];
var siblings = [].slice.call(div.parentNode.children) // convert to array
                 .filter(function(v) { return v !== div }); // remove element itself
console.log(siblings);

Ответ 4

Как насчет этого:

while ( node = node.previousElementSibling ) {
    if ( ( ' ' + node.className + ' ' ).indexOf( 'foo' ) !== -1 ) {
        // found; do your thing
        break;
    }
}

Не беспокойтесь, расскажите мне, что это не работает в IE8...

Ответ 6

Просто взгляните на как работает jQuery.

prevUntil: function( elem, i, until ) {
    return jQuery.dir( elem, "previousSibling", until );
},

Использует функцию while/looping caled dir(). Преобладание продолжается до тех пор, пока previousSibling не будет таким же, как элемент until.

dir: function( elem, dir, until ) {
    var matched = [],
        cur = elem[ dir ];

    while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
        if ( cur.nodeType === 1 ) {
            matched.push( cur );
        }
        cur = cur[dir];
    }
    return matched;
},

Ответ 7

У вас в основном есть getElementsByTagName и getElementsByName, они возвращают массивы и могут использовать wild cards. Если вы хотите, чтобы вам нужно было создать функцию или использовать то, что уже существует, как библиотека.

function getElements()
  {
  var x=document.getElementsByName("*");
  alert(x.length);
  }

update

getElementbyID возвращает только один элемент.

Ответ 8

Вы можете поместить весь процесс в одну строку, используя ES6:

const siblings = n => [...n.parentNode.children].filter(v => n !== v);

Удачи.