(function() { 'use strict'; const ths = document.getElementsByTagName('th'); // HTMLのタグを取得 //これら一つひとつに対して、イベントを設定していく let sortOder = 1; //1:昇順 -1:降順 function rebuildTbody(rows) { const tbody = document.querySelector('tbody'); //tbodyの中身をいったん全部消して並び替えられた配列の要素をtbodyの小要素として追加していく //tbodyの中身を消す let i; while (tbody.firstChild) { tbody.removeChild(tbody.firstChild); //最初の子要素をどんどん消していって、中身がなくなるまで行う } //tbodyに並び替えられたrowsの要素を追加していく for (i = 0; i < rows.length; i++) { tbody.appendChild(rows[i]); } } function updateClassName(th) { //並び順がわかりやすいようにアイコンをつけていく。アイコンの種類はクラスで管理していきたいのでsortOderに応じてthに対してクラスをつけていく。一旦thについているクラスをリセットした後に、クリックしたthに対してクラスをつけていく let k; for (k = 0; k < ths.length; k++) { ths[k].className = ''; } th.className = sortOrder === 1 ? 'asc':'desc'; } function compare(a, b, col,type) { let _a = a.children[col].textContent * 1; let _b = b.children[col].textContent * 1; if (type === "number") { _a = _a * 1;//*1で数値化 _b = _b * 1; } //数値がうまくいかない。(textContentで引っ張ってくるのはあくまでも文字列のため、文字列をそのまま比較してしまうと、先頭の1文字から順に比較してしまう。 //取得した値が数値かどうかを見出しにデータ属性をつけて、JSで取得して判定する else if (type === "string") { _a = _a.toLowerCase(); _b = _b.toLowerCase(); } //aにはtr要素が入っているのでそこから取り出す値->_a //tr要素の子要素であるtd要素ないのクリックされた列番目のものをひっぱてくればいいのでcllIndeexを使ってあげる。 //trの中のtdが引っ張ってこれたのでその中身をtextContentで引っ張ってきてあげる //大文字の方が小文字よりも先に来てしまっている(文字コードでいうと大文字の方が先に来るため) //比較する文字を一旦小文字にするtoLowerCase()を使う if (_a < _b) { //aがbより小さい場合 return -1; } if (_a > _b) { return 1; } return 0; //aとbが等しい場合 } function sortRows(th) { // sort // 配列にsortという命令をくっつけて、引数として関数を与える //この関数の返り値によって、昇順か降順かで並び替えてくれる(MDNで調べる) // const arr = ['taguchi', 'fkoji','dotinstall']; //const rows = document.querySelectorAll('tbody > tr'); // 今回並べ替えていきたいのはそれぞれの行なので、この行要素の入った配列を作ってあげる //querySelectorAllが返してくれるのは配列ではなく、Nodelistという型。 const rows = Array.prototype.slice.call(document.querySelectorAll('tbody > tr')); //Array.prototype.slice.callを使って配列化 const col = th.cellIndex; //このまま書くとfunctionの中のthisは違う意味になるから、一旦違う変数で受ける // console.log(rows); // return; let type = th.dataset.type; //string, number //今は見出しなのでこのクリックした見出しのデータ属性はdatasetで取れる rows.sort(function(a, b){ //tr, tr //a,bはtaguchi,fkoji,dotinstallが順次入ってくる //tr要素は複雑なデータになっているから、この中からある値を取り出して比較をする //tr要素の中にあるtd要素の内、クリックされた列番目の中身を引っ張る return compare(a, b, col, type) * sortOrder; }); return rows; } function setup() { let i; let rows; for (i = 0; i < ths.length; i++) { ths[i].addEventListener('click',function() { rows = sortRows(this); rebuildTbody(rows);//関数にしていく。名前は、tbodyを再構築しているから。 updateClassName(this);//thisが渡ってくる sortOrder *= -1; //最後にクリックしたら反転させたいから-1をかける }); } } setup(); })();