まず、inner/outerHTML を使用して DOM を操作することをすべて忘れてください。HTML のチャンクやドキュメントのセクションを挿入するのに便利ですが、一般的な DOM 操作を意図したものではありません。
DOM メソッドを使用します。
まず、すべての LI 要素を配列にロードします。次に、並べ替え関数を使用してそれらを並べ替えます。次に、UL 要素でラップされ、最初の文字が変わるたびにスパンで区切られた DOM に戻します。
編集
これが仕事をする関数です。それが本当に必要かどうかはわかりません。そうでない場合、関数ははるかに単純になります。
<script type="text/javascript">
// Simple helper
function getText(el) {
if (typeof el.textContent == 'string') {
return el.textContent.replace(/^\s+|\s+$/g,'');
}
if (typeof el.innerText == 'string') {
return el.innerText.replace(/^\s+|\s+$/g,'');
}
}
function sortLIs(id) {
// Get the element
var el = document.getElementById(id);
// Get the UL element that will be replaced
var sourceUl = el.getElementsByTagName('ul')[0];
// Get the LIs and put them into an array for sorting
var nodes = sourceUl.getElementsByTagName('li');
var li, lis = [];
for (var i=0, iLen=nodes.length; i<iLen; i++) {
lis[i] = nodes[i];
}
// Sort them
lis.sort(function(a, b) {
return getText(a) > getText(b)? 1 : -1;
});
// Now put them into the document in different ULs separated
// by spans.
// Create some temporary elements for cloning
var ul, ulo = document.createElement('ul');
var sp, spo = document.createElement('span');
var frag = document.createDocumentFragment(); // fragments are handy
var firstChar, currentChar;
// For each LI in the array...
for (i=0; i<iLen; i++) {
li = lis[i];
firstChar = getText(li).substr(0,1) || '';
// If first char doesn't match current, create a new span
// and UL for LIs
if (firstChar !== currentChar) {
currentChar = firstChar;
// New span
sp = spo.cloneNode(false);
sp.appendChild(document.createTextNode(firstChar.toUpperCase()));
sp.id = firstChar;
frag.appendChild(sp);
// New UL
ul = ulo.cloneNode(false);
frag.appendChild(ul);
}
// Add the li to the current ul
ul.appendChild(li);
}
// Replace the UL in the document with the fragment
el.replaceChild(frag, sourceUl);
}
</script>
<div id="x">
<ul>
<li>Cherry
<li>Banana
<li>Apple
<li>Blueberry
<li>Cranberry
<li>Blackberry
</ul>
</div>
<button onclick="sortLIs('x');">Sort</button>
LI がドキュメント フラグメントに移動されただけで、元の UL が複数の要素に置き換えられていることに注意してください。並べ替えが機能することを示すために、LI をごちゃ混ぜにしました。
編集 2
配列をテキストとして持っている場合、次のようになります。
var fruits = ['Cherry','Banana','Apple','Blueberry',
'Cranberry','Blackberry'].sort();
function insertFruits(id) {
var el = document.getElementById(id);
// Check that the above worked
if (!el) return;
var frag = document.createDocumentFragment();
var li, lio = document.createElement('li');
var ul, ulo = document.createElement('ul');
var sp, spo = document.createElement('span');
var firstChar, currentChar;
for (var i=0, iLen=fruits.length; i<iLen; i++) {
fruit = fruits[i];
firstChar = fruit.substr(0,1).toUpperCase();
if (firstChar !== currentChar) {
currentChar = firstChar;
sp = spo.cloneNode(false);
sp.appendChild(document.createTextNode(firstChar));
sp.id = firstChar;
frag.appendChild(sp);
ul = ulo.cloneNode(false);
frag.appendChild(ul);
}
li = lio.cloneNode(false);
li.appendChild(document.createTextNode(fruit));
ul.appendChild(li);
}
el.appendChild(frag);
}