2016-03-27 5 views
3

У меня есть traverse объект, содержащий два метода up() и down(), цели этих методов в цикле вверх или вниз через HTML ищет первое вхождение конкретного dataset-attribute и если найдены возвращения этого элемента ,Обход HTML структуру на поиск атрибута

«Определенный» dataset-attribute передается в качестве параметра в методы, например, у нас есть data-up и data-down.

var o1 = traverse.up(e.target,'up'); 
var o2 = traverse.down(e.target,'down'); 

Теперь обходе вверх метод traverse.up(e.target,'up') работает отлично, так как ParentNode это один-к-одному отношение к элементу щелкнул (e.target), однако моя проблема при попытке пройти вниз, так как элемент щелкнул (е .target) может иметь несколько дочерних элементов, мне нужно будет прокрутить каждый дочерний элемент и его дочерние элементы и т. д. ... найти атрибут .

Вопрос: Почему мой traverse.down(e.target,'down') метод возвращает первое вхождение в HTML-элемента с атрибутом ?

Вот JSFiddle демо

// HTML

<body> 
    <div id='black'> 
     <div id='red' data-up='upwards'> 
      <div id='blue'> 
       <div id='green'> 
        <div id='yellow'></div> 
        <div id='royalblue' data-down='downwards'></div> 
        <div id='fuscia'></div> 
       </div> 
      </div> 
     </div> 
    </div> 
</body> 

// JS

function init(){ 
    document.getElementById('black').addEventListener('click', handles); 
} 
function handles(e){ 
// var o1 = traverse.up(e.target,'up'); 
    var o2 = traverse.down(e.target,'down'); 
    console.log(o2); 
} 
traverse={ 
    up:function(o,a){ 
     while(o.dataset[a] === undefined){ 
      if(o.parentNode.tagName === 'HTML') break; 
      o = o.parentNode; 
     } 
     return o; 
    }, 
    down:function(o,a){ 
     if(o.dataset[a] === undefined){ 
      if(o.children.length > 0){ 
       o.children.forEach((o)=>{ 
        traverse.down(o,a); 
       }) 
      } 
      else console.log("DOES NOT HAVE CHILD"); 
     } 
     else{ 
      //console.log(o) **this does return the correct element with the data-down attribute however the return statement below isn't returning it back to the original caller. 
      return o; 
     } 
    } 
}; 
NodeList.prototype.forEach = HTMLCollection.prototype.forEach = Array.prototype.forEach; 
document.onreadystatechange=()=>(document.readyState === 'interactive') ? init() : null; 
+0

Вы должны, вероятно, 'Возвращение траверс. вниз (o, a); 'Или выяснить, что делать, если умножить e дочерние элементы содержат атрибут данных, которым вы пользуетесь. – James

+0

@James просто попробовал добавить return в forEach, все еще записывает 'undefined' –

+0

Да. У большинства детей этого не будет. Так что обнаружите, если они есть, и верните их. – James

ответ

1

Что-то вроде этого:

if(o.children.length > 0){ 
    o.children.forEach((o)=>{ 
     var t = traverse.down(o,a); 
     if (t) return t; // return the first element that matches. There might be more but we're ignoring them 
    }); 
    // none were found 
    return false; 
} 
+0

Я скопировал это, все еще не вернусь. –

+0

Если вы добавите 'console.log (o)' над символом 'return o;' в моем исходном коде, то последнее выражение else вы увидите, что 'o' является элементом html, содержащим атрибут' data-down', однако не верните его по какой-то причине. –

+0

Я понял, мы оба были близки, нам просто не нужно было использовать цикл forEach, возврат возвращался к функции forEach, а не вызывающей. –

 Смежные вопросы

  • Нет связанных вопросов^_^