LoginSignup
18
13

More than 5 years have passed since last update.

DOMを中の値でソートする

Posted at

何かを大量に一覧できるページを見てると特定の値でソートをしたいことが時々あります。(金額、参照回数、ブクマ数、コメント数など…)
サイト側にソートする機能が無い時は自分でコンソールなり、ユーザスクリプトでソートしてやります。

商品一覧で安い順にソートする例

<ul id="sec_forsale">
    <li>商品A<p class="price"><del>345円</del> 234円</p></li>
    <li>商品B<p class="price"><del>2,000円</del> 1,234円</p></li>
    <li>商品C<p class="price"><del>60円</del> 56円</p></li>
    <li>商品D<p class="price"><del>10円</del> 1円</p></li>
    <li>商品E<p class="price"><del>10円</del> 9円</p></li>
    <li>商品F<p class="price"><del>50円</del> 5円</p></li>
</ul>
var container = document.querySelector('#sec_forsale');
[].slice.call(container.querySelectorAll('li'))
    .map(function(v){
        var value = v.querySelector('.price').innerHTML.replace(/<.+>/,'').replace(/\D/g,'') - 0;
        return { dom: v, value: value };
    })
    .sort(function(a,b){ return a.value - b.value; })
    .forEach(function(v){ container.appendChild(v.dom); });

補足

  • querySelectorAll() の戻り値は NodeList を返し、配列系メソッドが使えないため、[].slice.call() で配列化しています。ES6に対応していれば Array.from() も使えます。
  • map 内では比較用の値をざっくり取り出し数値化しています。
  • また次に行う sort ではアルゴリズム上、比較対象を変えた上で1つの値を何度も評価しますので、パースが何度も行われないように要素と数値両方保持する形に持ち替えています。(シュワルツ変換)
  • sort内では持ち替えた .value の方を参照します。
  • このsortでは要素を持った配列の並び替えでしかないため最後のforEachでDOMに反映します。
18
13
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
13