2016-12-27 16 views
5

Mam następujące tablica i chcę utworzyć z niej nieuporządkowaną listę, ale mam problem z generowaniem listy nieuporządkowanej we właściwym formacie. Przeszukałem podobne pytania, ale żadne z istniejących rozwiązań nie działa na mój problem.JavaScript: Jak utworzyć nieuporządkowaną listę z tablicy?

var myArray = ['Value 1', ['Inner value 1', 'Inner value 2', 'Inner value 3', 'Inner value 4'], 'Value 2', 'Value 3', 'Value 4', 'Value 5', 'Value 6']; 

Oto mój kod JavaScript:

function arrToUl(arr) { 
    var div = document.getElementById('myList'); 
    var ul = document.createElement('ul'); 

    for (var i = 0; i < arr.length; i++) { 

    if (arr[i] instanceof Array) { 
     var list = arrToUl(arr[i]); 
    } else { 
     var li = document.createElement('li'); 
     li.appendChild(document.createTextNode(arr[i])); 
     console.log(ul.appendChild(li)); 
    } 
    div.appendChild(ul); 
    } 
} 

arrToUl(myArray); 

Powyższy kod powoduje następujący wynik:

<ul> 
<li>Value 1</li> 
<li>Inner Value 1</li> 
<li>Inner Value 2</li> 
<li>Inner Value 3</li> 
<li>Inner Value 4</li> 
<li>Value 2</li> 
<li>Value 3</li> 
<li>Value 4</li > 
<li>Value 5</li > 
<li>Value 6</li> 

Ale wynik powinien wyglądać jak poniżej:

<ul> 
<li>Value 1 
    <ul> 
     <li>Inner Value 1</li> 
     <li>Inner Value 2</li> 
     <li>Inner Value 3</li> 
     <li>Inner Value 4</li> 
    </ul> 
</li> 
<li>Value 2</li> 
<li>Value 3</li> 
<li>Value 4</li> 
<li>Value 5</li> 
<li>Value 6</li> 

Dziękuję za pomoc.

+0

Jakie jeżeli wynik gdyby myArray = [ 'wartość 1' [ 'wartość wewnętrznej 1', 'wartość wewnętrzna 2', 'wartość wewnętrzna 3', „wartość Wewnętrzna 4 '], [' Wartość wewnętrzna 5 ',' Wartość wewnętrzna 6 ',' Wartość wewnętrzna 7 ',' Wartość wewnętrzna 8 '], "Wartość 2", "Wartość 3", "Wartość 4", "Wartość 5", "Wartość 6"]? –

+0

Użycie * instanceof * do wykrycia tablicy jest niewiarygodne, użyj zamiast tego [* Array.isArray *] (http://ecma-international.org/ecma-262/7.0/index.html#sec-array.isarray). – RobG

Odpowiedz

5

Dołączyłeś wszystkie elementy <ul> do myList <div>. Aby to zmienić, dodałem nowy parametr do funkcji arrToUl(root, arr).

Nowy parametr, root, określa, do kogo ma zostać dołączone utworzone <ul>, więc jeśli funkcja napotyka pod-tablicę, używa poprzedniego elementu listy jako katalogu głównego do utworzenia podlisty.

var myArray = ['Value 1', ['Inner value 1', 'Inner value 2', 'Inner value 3', 'Inner value 4'], 'Value 2', 'Value 3', 'Value 4', 'Value 5', 'Value 6']; 
 

 
function arrToUl(root, arr) { 
 
    var ul = document.createElement('ul'); 
 
    var li; 
 
    
 
    root.appendChild(ul); // append the created ul to the root 
 

 
    arr.forEach(function(item) { 
 
    if (Array.isArray(item)) { // if it's an array 
 
     arrToUl(li, item); // call arrToUl with the li as the root 
 
     return; 
 
    } 
 
    
 
    li = document.createElement('li'); // create a new list item 
 
    li.appendChild(document.createTextNode(item)); // append the text to the li 
 
    ul.appendChild(li); // append the list item to the ul 
 
    }); 
 
} 
 

 
var div = document.getElementById('myList'); 
 

 
arrToUl(div, myArray);
<div id="myList"></div>

+0

'append' only ...? –

+0

Błąd: * "message": "Obiekt nie obsługuje właściwości lub metody" append "", * –

+0

teraz działa ... –

0

Można zapisać ostatnią li i dołączyć do niego z rozszerzonym z funkcji docelowej elementu DOM.

function iter(target) { 
 
    var ul = document.createElement('ul'), 
 
     li; 
 

 
    target.appendChild(ul); 
 
    return function (a) { 
 
     if (Array.isArray(a)) { 
 
      if (!li) { 
 
       li = document.createElement('li'); 
 
       ul.appendChild(li); 
 
      } 
 
      a.forEach(iter(li)); 
 
      return; 
 
     } 
 
     li = document.createElement('li'); 
 
     li.appendChild(document.createTextNode(a)); 
 
     ul.appendChild(li); 
 
    }; 
 
} 
 

 
var myArray = ['Value 1', ['Inner value 1', 'Inner value 2', 'Inner value 3', 'Inner value 4'], 'Value 2', 'Value 3', 'Value 4', 'Value 5', 'Value 6']; 
 

 
myArray.forEach(iter(document.getElementById('myList')));
<div id="myList"></div>

+0

Dzięki za pomoc. Wszystkie rozwiązania sprawdziły się dobrze. – EBamba

+0

@OriDrori, teraz sprawdza istnienie. –

0

Twój rekurencyjnej podejście nie mówi nic o tym, gdzie należy dołączyć nowe dziecko. Może powinieneś dać, za każdym razem, gdy dostajesz instancję tablicy, ostatni element to unikalny identyfikator. A potem możesz podać ten identyfikator za pomocą funkcji paramerów.

GUID Generator to dobry sposób na stworzenie unikalnego identyfikatora.

+0

To nie jest odpowiedź, powinien to być komentarz. – RobG

0

Proponuję rozwiązanie oparte na rekurencji, wydaje mi się jaśniejsze i mniej podatne na błędy. Tworzy nieco inny wynik, ponieważ mapuje każdy element tablicy do węzła na tym samym poziomie i myślę, że powinien to być wynik utworzenia ul z tablicy.

var myArray = [ 
    'Value 1', 
    ['Inner value 1', 'Inner value 2', 'Inner value 3', 'Inner value 4'], 
    'Value 2', 
    'Value 3', 
    'Value 4', 
    'Value 5', 
    'Value 6' 
]; 

function appendItems(arr, el) { 
    if(!arr.length) return el; 
    else { 
     var head = arr.shift(); 
     var child = transform(head); 
     var li = document.createElement('li'); 
     li.appendChild(child); 
     el.appendChild(li); 
     return appendItems(arr, el); 
    } 
} 

function transform(item) { 
    if(Array.isArray(item)) { 
    var ul = document.createElement('ul'); 
    return appendItems(item, ul); 
    } else { 
    return document.createTextNode(item); 
    } 
} 

var ul = transform(myArray); 

Jeśli chciałbyś uzyskać wyjście, o którym wspomniałeś, może lepiej zmienić format wejściowy, aby dopasować jedną iterację na węzeł. Ex:

var arr = [ 
    {label: 'value1', subitems: ['Inner value 1', 'Inner value 2', 'Inner value 3', 'Inner value 4']} 
]; 
1

Twoja funkcja nazywa arrToUl, więc należy po prostu zrobić: przekształcić tablicę do ul.

Po uzyskaniu ul można go wstawić w dowolnym miejscu, ale usunąć poza funkcję.

Potem wszystko staje się jasne.

function arrToUl(arr) { 
 
    var ul = document.createElement('ul'), li; 
 
    for (var i = 0; i < arr.length; i++) { 
 
    if (Array.isArray(arr[i])) { 
 
     li.appendChild(arrToUl(arr[i])); 
 
    } else { 
 
     li = document.createElement('li'); 
 
     li.appendChild(document.createTextNode(arr[i])); 
 
     ul.appendChild(li); 
 
    } 
 
    } 
 
    return ul; 
 
} 
 
var myArray = ['Value 1', ['Inner value 1', 'Inner value 2', 'Inner value 3', 'Inner value 4'], 'Value 2', 'Value 3', 'Value 4', 'Value 5', 'Value 6']; 
 
document.body.appendChild(arrToUl(myArray));

Powiązane problemy