2016-06-02 3 views
0

Ich versuche, eine rekursive Funktion zu verwenden, um mehrere verschachtelte UL/LI-Elemente im DOM anzuzeigen/auszublenden.Rekursive Funktion für untergeordnete DOM-Elemente

Ich habe eine Funktion, die für einzelne verschachtelt funktioniert, aber ich versuche, eine rekursive Funktion zu verwenden, um eine Menge verschachtelter Elemente zu steuern x. Hier

ist, was ich derzeit haben:

HTML

<section data-range="true"> 
    <input type="range"> 
    <ul> 
    <li>Item one</li> 
    <li>Item two</li> 
    <ul> 
     <li>Nestd two-one</li> 
     <li>Nestd two-two</li> 
     <ul> 
     <li>Double-nested one</li> 
     </ul> 
    </ul> 
    <li>Item three</li> 
    </ul> 
</section> 

JS:

/* eventListener 
* Attach an event listener to this element 
* 
* @param Object - Event object 
*/ 
function eventListener(el) { 
    el.addEventListener('change', function(e) { 
     // List 
     else if (el.parentNode.children[1].nodeName == "UL" || el.parentNode.children[1].nodeName == "OL") { 
      updateList(e, el.value); 
     } 
    }); 
} 

/* updateList 
* 
* @param Object - Event object 
* @param Real - Range value (i.e. 3.2) 
*/ 
function updateList(e, range) { 
    var target = e.srcElement || e.target; 
    var list = target.nextSibling.nextElementSibling; 
    var listNumber = list.childElementCount; 

    displayChildren(list, listNumber); 
} 

/* displayChildren 
* 
* @param Object - Event object 
*/ 
function displayChildren(list, listNumber) { 

    for (var i = 0; i < listNumber; i++) { 
     if (list.children[i].nodeName != 'UL') { 
      list.children[i].style.display = (list.children[i].getAttribute('data-position') <= range) ? "":"none"; 
     } 
     if (list.children[i].children.length > 0) { 
      displayChildren(list.children[i], list.children[i].childElementCount); 
     } 
    } 
} 

Hier sind einige aktuelle Beispiel:

  • JSbin mit rekursive Funktion auf verschachtelte Elemente.
  • JSbin mit funktionierenden verschachtelten Elementen.

Alle hilfreiche Tipps werden geschätzt.

+1

Bitte beschreiben Sie detaillierter, was Sie zu erreichen versuchen. Bitte zeigen oder beschreiben Sie vorher/nachher Ergebnisse, damit wir genau sehen können, womit Sie anfangen und womit Sie enden möchten. – jfriend00

Antwort

1

Nun, Sie lassen nur einige Parameter weg. :)

Check it JsBin

function updateList(e, range) { 
    ... 
    displayChildren(list, listNumber, range); // add range param. 
} 

function displayChildren(list, listNumber, range) { // and here 
    ... 
    displayChildren(list.children[i], list.children[i].childElementCount, range); // and here. 

Warum jQuery nicht verwenden? wie auch immer, es ist cool Skript Sie gemacht haben, viel Glück :)

---- EDIT

Ihre Daten-Position und Werte der Eingangsbereich sind keine ‚Nummer‘, sie sind ‚String‘.

Also, wenn mehr als 10 'UL' Elemente vergleicht es wie '10' mit '4' (und '4' ist größer Wert ')

JsBin (working demo)

es zu beheben, konvertieren Nummer eingeben, bevor vergleichen sie bei

function eventListener(el) { 
    ... 
    updateList(e, parseInt(el.value)); 


function displayChildren(list, listNumber, range) { 
    ... 
    // Now range is Number. (and LHS will converted with number) 
    list.children[i].style.display = (list.children[i].getAttribute('data-position') <= range) ? "":"none"; 

ich glaube, du es schon bekommen, check it out :) Javascript string/integer comparisons

---- bearbeitet wieder

Und .. Wenn Sie nur 'LI' Elemente zeigen und verbergen möchten, wie wäre es damit?

var Range = function(step) { 
    var rangeElements = document.querySelectorAll("[data-range]"); 

    for(var i = 0; i < rangeElements.length; i++) { 
    var el = rangeElements[i]; 
    var inputRange = el.children[0]; // input type="range" 
    var sectionRange = el.children[1]; // root UL 

    inputRange.min = 0; 
    inputRange.max = inputRange.value = sectionRange.getElementsByTagName('LI').length; 
    inputRange.step = Number(step) || 1; 

    // for better UX use oninput event. 
    inputRange.addEventListener('input', function(e) { 
     var el = e.target; 
     var rangeItems = el.parentNode.children[1].getElementsByTagName('LI'); 
     var range = Number(el.value); 
     for(var i = 0; i < rangeItems.length; i++) { rangeItems[i].style.display = i < range ? '' : 'none'; } 
    }); 
    } 
    return rangeElements; 
} 
+1

Und es ist besser, halte 'UL' Element zu verstecken, wenn es keine sichtbaren 'LI' Kinder gibt. –

+0

Danke! Es ist immer so etwas wie dieses ... Wie auch immer, dieses Projekt ist Open-Source auf GitHub sowie –

+0

Oh .. Ich sehe, danke für Ihre Annahme. Viel Glück! –