2016-05-24 7 views
3

各項目のdata-char値を使用して、このULを数値順およびアルファベット順にソートしたいと考えています。各項目のdata-char値を使用して、数値順にアルファベット順にソート

注:子ULエレメントではなく、親ULのみをソートしたいだけです。

<ul> 
    <li data-char="w"> 
    <span>W</span> 
    <ul> 
     <li>WWWWWWWWWWWWWW</li> 
    </ul> 
    </li> 
    <li data-char="5"> 
    <span>5</span> 
    <ul> 
     <li>55555555555555</li> 
    </ul> 
    </li> 
    <li data-char="a"> 
    <span>A</span> 
    <ul> 
     <li>AAAAAAAAAAAAAA</li> 
    </ul> 
    </li> 
    <li data-char="1"> 
    <span>1</span> 
    <ul> 
     <li>11111111111</li> 
    </ul> 
    </li> 
</ul> 

私が実行してjQueryを使ってこれを実現することができるよ:

function sortCharLi(a, b) { 

    var va = a.dataset.char.toString().charCodeAt(0), 
     vb = b.dataset.char.toString().charCodeAt(0); 

    // add weight if it's a number 
    if (va < 'a'.charCodeAt(0)) va += 100; 
    if (vb < 'a'.charCodeAt(0)) vb += 100; 

    return vb < va ? 1 : -1; 
} 

$('ul > li').sort(sortCharLi).appendTo('ul'); 

をしかし、私はそれはもはや選択肢ではありませんので、jQueryの依存関係を削除する必要よ。

どのように私はjQueryなしでこれを行うことができます任意のアイデア?

JSBIN

答えて

1

これは私が仕事からオフにスナップすることができます最良の答えですが、それはあなたのHTML構造に合わせて調整する必要があるかもしれません。

のjQueryなしULをソートするFUNCTION:

function sortUnorderedList(ul, sortDescending) { 
if(typeof ul == "string") 
    ul = document.getElementById(ul); 

    // Idiot-proof, remove if you want 
    if(!ul) { 
    alert("The UL object is null!"); 
    return; 
    } 

    // Get the list items and setup an array for sorting 
    var lis = ul.getElementsByTagName("LI"); 
    var vals = []; 

// Populate the array 
    for(var i = 0, l = lis.length; i < l; i++) 
    vals.push(lis[i].innerHTML); 

    // Sort it 
    vals.sort(); 

    // Sometimes you gotta DESC 
    if(sortDescending) 
    vals.reverse(); 

// Change the list on the page 
    for(var i = 0, l = lis.length; i < l; i++) 
    lis[i].innerHTML = vals[i]; 
} 

USAGE:

sortUnorderedList("ID_OF_LIST"); 
+0

あなたのコードは、要素を並べ替える。さらに、既存のデータ構造を破壊します。 – zeroflagL

2

この関数は、元のソーターの方法を保持します。この関数はul要素が渡されることを想定しています

function sortThem(ul) { 
    var nodes = Array.prototype.slice.call(ul.childNodes).filter(function(el) { 
     // Could use QSA with scope depending on browser support here 
     return el.tagName === 'LI'; 
    }); 

    nodes.sort(function(a, b) { 
     var va = a.getAttribute('data-char').charCodeAt(0), 
      vb = b.getAttribute('data-char').charCodeAt(0); 

     // add weight if it's a number 
     if (va < 'a'.charCodeAt(0)) va += 100; 
     if (vb < 'a'.charCodeAt(0)) vb += 100; 

     return vb < va ? 1 : -1; 
    }); 

    nodes.forEach(function(node) { 
     ul.appendChild(node); 
    }); 
} 
6

あなたはchildrenプロパティを使用して、要素オブジェクトから取得することができgetElemetsByTagNameと子供liを使用してulを得ることができます。

function order(ul) { 
 
    // get html children elements of li 
 
    // in case of ul children will be li 
 
    // ` Array.from` will hell helps to convert them into array 
 
    var elements = Array.from(ul.children); 
 

 
    // sort them with the same code 
 
    elements.sort(function(a, b) { 
 
    var va = a.getAttribute('data-char').charCodeAt(0), 
 
     vb = b.getAttribute('data-char').charCodeAt(0), 
 
     charCA = 'a'.charCodeAt(0); 
 

 
    // add weight if it's a number 
 
    if (va < charCA) va += 100; 
 
    if (vb < charCA) vb += 100; 
 
    // just get the difference and return to sort them 
 
    return va - vb; 
 
    }); 
 

 
    // append back to update the order 
 
    // forEach can be used to update since it's in array format 
 
    elements.forEach(function(ele) { 
 
    ul.appendChild(ele) 
 
    }); 
 
} 
 

 

 
// get ul tag from dom and pass as parameter 
 
// although you can use id selector or querySelector, etc 
 
// it depends up on your need, here you just need to pass the dom reference of `ul` to be sorted 
 
order(document.getElementsByTagName('ul')[0]);
<ul> 
 
    <li data-char="w"> 
 
    <span>W</span> 
 
    <ul> 
 
     <li>WWWWWWWWWWWWWW</li> 
 
    </ul> 
 
    </li> 
 
    <li data-char="5"> 
 
    <span>5</span> 
 
    <ul> 
 
     <li>55555555555555</li> 
 
    </ul> 
 
    </li> 
 
    <li data-char="a"> 
 
    <span>A</span> 
 
    <ul> 
 
     <li>AAAAAAAAAAAAAA</li> 
 
    </ul> 
 
    </li> 
 
    <li data-char="1"> 
 
    <span>1</span> 
 
    <ul> 
 
     <li>11111111111</li> 
 
    </ul> 
 
    </li> 
 
</ul>


UPDATE: あなたはjQueryののようにチェーンにそれらを使用したい場合は、プロトタイプを拡張

NodeList.prototype.sortElements = function(custom) { 
 
    // if custom sort function passed then sort based on that 
 
    if (typeof custom === 'function') 
 
    return [].slice.call(this).sort(custom); 
 
    // otherwise apply sort method directly 
 
    return [].slice.call(this).sort(); 
 
    // you can also use Array.from(this), which only works in latest browsers 
 
} 
 

 
Array.prototype.updateOrder = function() { 
 
    // iterate over array element 
 
    this.forEach(function(ele) { 
 
    // append to the parent element 
 
    ele.parentNode.appendChild(ele); 
 
    }) 
 
} 
 

 
// sort them with the same code 
 
function sortFn(a, b) { 
 
    var va = a.getAttribute('data-char').charCodeAt(0), 
 
    vb = b.getAttribute('data-char').charCodeAt(0), 
 
    charCA = 'a'.charCodeAt(0); 
 
    // add weight if it's a number 
 
    if (va < charCA) va += 100; 
 
    if (vb < charCA) vb += 100; 
 
    // just get the difference and return to sort them 
 
    return va - vb; 
 
} 
 

 

 
// get li elements which have `data-char` attribute 
 
document.querySelectorAll('ul li[data-char]') 
 
    .sortElements(sortFn) // call sortElements methods we defined with custom sort function 
 
    .updateOrder(); // call updateOrder to update the order of element
<ul> 
 
    <li data-char="w"> 
 
    <span>W</span> 
 
    <ul> 
 
     <li>WWWWWWWWWWWWWW</li> 
 
    </ul> 
 
    </li> 
 
    <li data-char="5"> 
 
    <span>5</span> 
 
    <ul> 
 
     <li>55555555555555</li> 
 
    </ul> 
 
    </li> 
 
    <li data-char="a"> 
 
    <span>A</span> 
 
    <ul> 
 
     <li>AAAAAAAAAAAAAA</li> 
 
    </ul> 
 
    </li> 
 
    <li data-char="1"> 
 
    <span>1</span> 
 
    <ul> 
 
     <li>11111111111</li> 
 
    </ul> 
 
    </li> 
 
</ul>

2

$('ul > li')にはquerySelectorAllを使用できます。注意してください。右のセレクタは$('ul > li[data-char]')である必要があります。これは、属性としてdata-charを持つliタグでのみ除外されるためです。

querySelectorAllから返されたNodeListを配列に変換するには、Array.fromを使用できます。

appendToの代わりにforEachを使用できます。

ので、コードは次のようになります。

function sortCharLi(a, b) { 
 
    var va = a.getAttribute('data-char').charCodeAt(0), 
 
     vb = b.getAttribute('data-char').charCodeAt(0); 
 

 
    // add weight if it's a number 
 
    if (va < 'a'.charCodeAt(0)) va += 100; 
 
    if (vb < 'a'.charCodeAt(0)) vb += 100; 
 

 
    return vb < va ? 1 : -1; 
 
} 
 

 
window.onload = function() { 
 
    // $('ul > li').sort(sortCharLi).appendTo('ul'); 
 
    
 
    Array.from(document.querySelectorAll('ul > li[data-char]')).sort(sortCharLi).forEach(function(element, index) { 
 
    element.parentNode.appendChild(element); 
 
    }); 
 
}
<ul> 
 
    <li data-char="w"> 
 
     <span>W</span> 
 
     <ul> 
 
      <li>WWWWWWWWWWWWWW</li> 
 
     </ul> 
 
    </li> 
 
    <li data-char="5"> 
 
     <span>5</span> 
 
     <ul> 
 
      <li>55555555555555</li> 
 
     </ul> 
 
    </li> 
 
    <li data-char="a"> 
 
     <span>A</span> 
 
     <ul> 
 
      <li>AAAAAAAAAAAAAA</li> 
 
     </ul> 
 
    </li> 
 
    <li data-char="1"> 
 
     <span>1</span> 
 
     <ul> 
 
      <li>11111111111</li> 
 
     </ul> 
 
    </li> 
 
</ul>

UPDATE 変換する短い方法:純粋なJavaScriptに

$('ul > li[data-char]').sort(sortCharLi).appendTo('ul'); 

ができ:

以下の方法を追加する必要があり、この結果を達成するために210
document.querySelectorAll('ul > li[data-char]').sort(sortCharLi).replaceWith(); 

NodeList.prototype.sort = function(callBack) { 
    if (typeof callBack === 'function') { 
     return [].slice.call(this).sort(callBack); 
    } else { 
     return [].slice.call(this).sort(); 
    } 
} 

Array.prototype.replaceWith = function() { 
    this.forEach(function(element, index) { 
     element.parentNode.appendChild(element); 
    }); 
    return this; 

}

このようにjQueryの中のような連鎖方法に可能性が存在する:

function sortCharLi(a, b) { 
 
    var va = a.getAttribute('data-char').charCodeAt(0), 
 
     vb = b.getAttribute('data-char').charCodeAt(0); 
 

 
    // add weight if it's a number 
 
    if (va < 'a'.charCodeAt(0)) va += 100; 
 
    if (vb < 'a'.charCodeAt(0)) vb += 100; 
 

 
    return vb < va ? 1 : -1; 
 
} 
 

 
NodeList.prototype.sort = function(callBack) { 
 
    if (typeof callBack === 'function') { 
 
    return [].slice.call(this).sort(callBack); 
 
    } else { 
 
    return [].slice.call(this).sort(); 
 
    } 
 
} 
 

 
Array.prototype.replaceWith = function() { 
 
    this.forEach(function(element, index) { 
 
    element.parentNode.appendChild(element); 
 
    }); 
 
    return this; 
 
} 
 

 
window.onload = function() { 
 
    document.querySelectorAll('ul > li[data-char]').sort(sortCharLi).replaceWith(); 
 
}
<ul> 
 
    <li data-char="w"> 
 
     <span>W</span> 
 
     <ul> 
 
      <li>WWWWWWWWWWWWWW</li> 
 
     </ul> 
 
    </li> 
 
    <li data-char="5"> 
 
     <span>5</span> 
 
     <ul> 
 
      <li>55555555555555</li> 
 
     </ul> 
 
    </li> 
 
    <li data-char="a"> 
 
     <span>A</span> 
 
     <ul> 
 
      <li>AAAAAAAAAAAAAA</li> 
 
     </ul> 
 
    </li> 
 
    <li data-char="1"> 
 
     <span>1</span> 
 
     <ul> 
 
      <li>11111111111</li> 
 
     </ul> 
 
    </li> 
 
</ul>

関連する問題