¿Cómo puedo ordenar alfabéticamente una lista desordenada mientras conservo el html externo? Mi configuración actual ordena la lista alfabéticamente, sin embargo, solo reorganiza el html interno de los elementos de la lista en lugar del elemento completo, lo cual es un problema porque dentro de la etiqueta tengo llamadas de script basadas en eventos que son específicas para cada elemento. Los elementos de la lista en sí mismos se agregan mediante un script desde un documento xml. Aquí está el html:
var xhttp; xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { onLoad(this); } }; xhttp.open("GET", "stocks.xml", true); xhttp.send(); function onLoad(xml) { var x, i, txt, xmlDoc; xmlDoc = xml.responseXML; txt = "<ul id = stocksymbols>"; var StockList; x = xmlDoc.getElementsByTagName("Stock"); for (i = 0; i < x.length; i++) { symbol = x[i].getAttribute('symbol'); txt += "<li onmouseover=\"mouseOver('" + symbol + "')\" onmouseout=\"mouseOut()\">" + symbol + "</li>"; } document.getElementById("stockList").innerHTML = txt + "</ul>"; sortList("stocksymbols"); } function sortList(ul) { if (typeof ul == "string") ul = document.getElementById(ul); var lis = ul.getElementsByTagName("LI"); var vals = []; for (var i = 0, l = lis.length; i < l; i++) vals.push(lis[i].innerHTML); vals.sort(); for (var i = 0, l = lis.length; i < l; i++) lis[i].innerHTML = vals[i]; } function mouseOver(target) { stockInfoDiv = document.getElementById("stockInfo"); stockInfoDiv.innerHTML = target; } function mouseOut() { stockInfoDiv.innerHTML = ""; }
h2 { color: Navy; } li { font-family: monospace; font-weight: bold; color: Navy; } li:hover { font-family: monospace; font-weight: bold; color: red; }
<html> <head> <title></title> </head> <body> <h2>List of Stocks:</h2> <div id="stockList"> </div> <br /> <br /> <br /> <div id="stockInfo"> </div> </body> </html>
En lugar de lis[i].innerHTML = vals[i];
, ordene la lista lis
y haga ul.appendChild(lis[i])
. Esto eliminará el li
actual de su posición en el DOM y lo agregará al final de ul
. Supongo que los únicos elementos li
son hijos directos de ul
.
function sortList(ul) { var ul = document.getElementById(ul); Array.from(ul.getElementsByTagName("LI")) .sort((a, b) => a.textContent.localeCompare(b.textContent)) .forEach(li => ul.appendChild(li)); } sortList("stocksymbols");
<ul id=stocksymbols> <li>AAA</li> <li>ZZZ</li> <li>MMM</li> <li>BBB</li> </ul>
<ul id="mylist"> <li id="list-item3">text 3</li> <li id="list-item4">text 4</li> <li id="list-item2">text 2</li> <li id="list-item1">text 1</li> </ul> <script> var list = document.getElementById('mylist'); var items = list.childNodes; var itemsArr = []; for (var i in items) { if (items[i].nodeType == 1) { // get rid of the whitespace text nodes itemsArr.push(items[i]); } } itemsArr.sort(function(a, b) { return a.innerHTML == b.innerHTML ? 0 : (a.innerHTML > b.innerHTML ? 1 : -1); }); for (i = 0; i < itemsArr.length; ++i) { list.appendChild(itemsArr[i]); } </script>
Entonces, hagámoslo con el XML, construyamos una matriz, clasifiquemos la matriz y luego construyamos la lista.
var symbols = xmlDoc.getElementsByTagName("Stock"); var items = []; for (var i = 0; i < symbols.length; i++) { items.push(symbols[i].getAttribute('symbol')); //build array of the symbols } var lis = items.sort() //sort the array .map( function(txt) { //loop over array return "<li>" + txt + "</li>"; //build the li }).join(""); //join the indexes as one string console.log(lis); //the lis in a string.