Heim > Artikel > Web-Frontend > Native JS implementiert die Tabellensortierung
Ich habe kürzlich das Sortieren von Tabellen in JS gelernt und nicht erwartet, dass das unauffällige Sortieren von Tabellen tatsächlich viele JS-Wissenspunkte impliziert. Zeichnen Sie diesen Lernprozess hier auf. Ich hoffe, es hilft auch allen.
Die vollständige Tabellensortierung umfasst die folgenden Wissenspunkte:
Aufrufmethode verwendet die
Sortiermethode im Detail
Datenbindung
DOM-Mapping
Im Folgenden werden diese Wissenspunkte detailliert zusammengefasst und schließlich kombiniert Wissenspunkte implementieren den folgenden Tabellensortierungsfall.
Vollständiger Fallquellcode: https://github.com/daweihe/JS...
Die Funktion der Aufrufmethode besteht darin, diesen Zeiger in der Methode zu ändern.
Aufruf Diese Methode ist in Function.prototype
definiert. Jede von uns definierte Funktion kann als Instanz der Klasse Function
betrachtet werden. Anschließend können Sie den Prototyp der Klasse über das Attribut __proto__
der Instanz finden. Jede Funktion kann Methoden wie call
und apply
aufrufen.
Schauen wir uns zunächst ein Beispiel an:
var obj = { name : 'JS' } function testCall () { console.log(this); } testCall.call( obj ); // {name: "JS"}
Zuerst findet die Funktion testCall
die Aufrufmethode über den Prototypketten-Suchmechanismus und führt sie während des Ausführungsprozesses aus Methode platziert die Aufrufmethode in der Funktionsinstanz. Dies wird in den ersten Parameter von Aufruf geändert, und dann wird die Instanzfunktion der Aufrufmethode aufgerufen und ausgeführt.
Sehen Sie sich zwei Fragen an:
function fn1() { console.log(1); console.log(this); } function fn2() { console.log(2); console.log(this); } fn1.call(fn2); //this -> fn2 fn1.call.call(fn2); //这里的call是改变function.__proto__.call的call方法中的this,相当于执行参数
Wenn die Aufrufmethode ausgeführt wird, wird der erste Parameter der Aufrufmethode verwendet, um dies zu ändern, und ab dem zweiten Parameter werden Parameter übergeben der Funktionsaufruf.
Wenn im nicht-strikten Modus keine Parameter an die Aufrufmethode übergeben werden oder null oder undefiniert übergeben wird, zeigt dies auf window
.
sum.call(); //window sum.call(null); //window sum.call(undefined); //window
Die Aufrufausführung im strikten Modus unterscheidet sich von der im nicht strikten Modus:
sum.call(); //undefined sum.call(null); //null sum.call(undefined); //undefined
Im Folgenden wird die Aufrufmethode verwendet, um eine Methode zum Konvertieren eines Klassenarrays zu implementieren ein Array:
function listToArray (likeAry) { var ary = []; try { ary = Array.prototype.slice.call(likeAry); } catch (e) { for (var i = 0; i < likeAry.length; i ++) { ary[ary.length] = likeAry[i]; } } return ary; }
Zu den Aufrufmethoden gehören die Apply- und Bind-Methoden. Hier ist eine kurze Zusammenfassung.
Die Apply-Methode funktioniert genauso wie die Call-Methode, außer dass die Form der Parameterübergabe unterschiedlich ist. Apply verpackt die Parameter der Funktion in ein Array:
function sum(num1, num2) { console.log(num2 + num1); console.log(this); } sum.apply(null,[100,200]);
Die Bindung Die Methode wird auch zum Ändern verwendet. Das Schlüsselwort this wird verwendet, aber es ändert nur den Sinn von this und führt nicht sofort die Funktion aus, die this aufruft.
function sum(num1, num2) { console.log(num2 + num1); console.log(this); } var obj = {name : 'zx'} var temp = sum.bind(obj); //temp已经是被改变了this的函数 temp(100,200); //当我们需要的时候才执行 //或者像这样处理 var temp = sum.bind(null, 100, 200); temp();
Bind-Methode verkörpert die Vorverarbeitungsidee in js.
Wir wissen, dass die sort
-Methode von Arrays nur Arrays innerhalb von 10 sortieren kann. Wenn das zu sortierende Array Zahlen größer als 10 enthält, müssen wir die Rückruffunktion an die sort
-Methode übergeben. Die übliche lautet wie folgt:
ary.sort(function (a,b) { return a - b; });
Auf diese Weise wird die Array kann in aufsteigender Reihenfolge sortiert werden. Was ist also das Prinzip dieser Sortierung?
Für die beiden übergebenen Parameter gilt: a
stellt das aktuelle Element im gefundenen Array dar und b
stellt das Element nach dem aktuellen Element dar.
return a -b
: Wenn a größer als b ist, wird das Ergebnis zurückgegeben und a und b tauschen die Positionen. Wenn a kleiner als b ist, bleiben die Positionen von a und b unverändert. Dies ist die aufsteigende Sortierung
return b -a
: Wenn b größer als a ist, wird das Ergebnis zurückgegeben und a und b tauschen die Positionen. Wenn a kleiner als b ist, bleiben die Positionen von a und b unverändert. Dies ist eine absteigende Reihenfolge
Wie sortiert man ein solches zweidimensionales Array nach Alter, nachdem man die Grundprinzipien verstanden hat?
var persons = [{ name:'dawei', age:55 },{ name:'ahung', age:3 },{ name:'maomi', age:2 },{ name:'heizi', age:78 },{ name:'afu', age:32 }];
Eigentlich ist es ganz einfach:
ary.sort(function(a,b){ return a.age - b.age; });
Wenn Sie nach Namen sortieren, ist die localeCompare()
-Methode der Zeichenfolge beteiligt:
ary.sort(function(a,b){ return a.name.localeCompare(b.name); });
name.localeCompare()
Diese Methode vergleicht die Buchstaben der beiden Zeichenfolgen unter den 24 englischen Buchstaben, wenn der erste Buchstabe der vorherigen Zeichenfolge früher erscheint als das erste Zeichen der zweiten Zeichenfolge. Geben Sie <🎜 zurück >. Wenn es später erscheint, wird die erste Zeichenfolge als größer betrachtet und 1 zurückgegeben. Wenn die verglichenen Zeichen gleich sind. Vergleichen Sie dann das nächste Zeichen. -1
//ary为需要添加到页面中的数据数组 var op = document.getElementById("box");//获取容器 var myUl = op.getElementsByTagName("ul")[0];//获取列表 var arrLength = ary.length; for (var i = 0;i < arrLength ; i ++) { //动态创建元素 var oli = document.createElement("li"); oli.innerHTML = '<span>' + (i + 5) + '</span>' + ary[i].title; myUl.appendChild(oli);//动态添加元素 }Jede Hinzufügung führt zu einem DOM-Reflow. Wenn die Datenmenge zu groß ist, beeinträchtigt dies die Leistung erheblich. Bezüglich DOM-Reflow und Neuzeichnen empfehle ich Ihnen, diesen Artikel zu lesen: http://www.css88.com/archives...Strings verbinden:
var str = ""; for(var i=0; i<ary.length; i++){ str += '<li>'; str += '<span>'; str += (i+5); str += '</span>'; str += ary[i].title; str += '</li>'; } myUl.innerHTML += str;Obwohl diese Methode nur einen Reflow verursacht, werden alle Ereignisse und Attribute aus den ursprünglichen Elementen entfernt. Wenn wir der Liste ein Ereignis für das li-Tag hinzufügen, wenn die Maus hinein bewegt wird und der Hintergrund seine Farbe ändert, macht diese Methode dieses Ereignis ungültig. Um die durch die beiden oben genannten Datenbindungsmethoden verursachten Probleme zu lösen, verwenden wir Dokumentfragmente zum Hinzufügen von Daten.
var frg = document.createDocumentFragment();//创建文档碎片 for (var i =0; i <ary.length ;i ++ ){ var li = document.createElement("li"); li.innerHTML = '<span>' + ( i + 5 ) + '</span>' + ary[i].title; frg.appendChild(li);//将数据动态添加至文档碎片中 } myUl.appendChild(frg); //将数据一次性添加到页面中 frg = null; //释放内存Dies führt nur einmal zu einem DOM-Reflow und behält die ursprünglich vorhandenen Ereignisse bei.
DOM映射机制:所谓映射,就是指两个元素集之间元素相互“对应”的关系。页面中的标签集合和在JS中获取到的元素对象(元素集合)就是这样的关系。如果页面中的HTML标签结构发送变化,那么集合中对应的内容也会跟着自动改变。
<ul id="myul"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> </ul>
对于这样一个列表使用下列脚本:
var myul = document.getElementById("myul"); var mylis = myul.getElementsByTagName('li'); for (var i = mylis.length - 1 ; i >= 0; i --) { myul.appendChild(mylis[i]); } console.log(mylis.length); // 5
将获取到的列表元素反序重新插入ul中,那么ul列表会变成下面这样:
<ul id="myul"> <li>5</li> <li>4</li> <li>3</li> <li>2</li> <li>1</li> </ul>
我们看到列表的长度依然是5,只是位置颠倒了。这是因为每个li标签和JS中获取的标签对象存在一个对应关系,当某个标签被重新插入到页面中时,页面中对应的标签会移动到插入的位置。这就是DOM映射。
之所以使用动态获取数据,是为了使用文档碎片绑定数据。
var res = ''; //声明一个全局变量,接收数据 var xhr = new XMLHttpRequest(); xhr.open('get', 'date.txt', false); xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { res = JSON.parse(xhr.responseText); } } xhr.send(null);
此时数据就保存在了res
这个全局变量之中。
var frg = document.createDocumentFragment(); for (let i = 0; i < res.length; i++) { var tr = document.createElement("tr"); for (key in res[i]) { var td = document.createElement("td"); td.innerHTML = res[i][key]; tr.appendChild(td); } frg.appendChild(tr); } tbody.appendChild(frg);
这里涉及的点较多
//为两列添加点击事件 for (let i = 0; i < ths.length; i++) { let curTh = ths[i]; curTh.sortFlag = -1; //用于对列进行升降序排列 curTh.index = i; //记录当前点击列的索引,便于排序操作 if (curTh.className == 'sort') { curTh.onclick = function() { sort.call(this); //改变排序函数内this的指向,让其指向当前点击列 } } } //排序方法 function sort() { //对数组元素进行排序 let target = this; //这里将this取出,因为在sort方法里需要使用该this,但是sort方法里的this是调用方法的数组 this.sortFlag *= -1; //1 代表升序 -1代表降序 let ary = listToArray(bodyTrs); //获取body数据 ary = ary.sort(function(a, b) { let one = a.cells[target.index].innerHTML; let two = b.cells[target.index].innerHTML; let oneNum = parseFloat(one); let twoNum = parseFloat(two); if (isNaN(oneNum) || isNaN(two)) { return one.localeCompare(two) * target.sortFlag; } else { return (oneNum - twoNum) * target.sortFlag; } }); //把排好序的数组重新写入页面 let frg = document.createDocumentFragment(); for (let i = 0; i < ary.length; i++) { rg.appendChild(ary[i]); } tbody.appendChild(frg); frg = null; //点击某列时,要将其他列的排序标志恢复为-1,让下次再点击任意一个标签时都是默认是升序排列 for (let i = 0; i < ths.length; i++) { if (ths[i] != this) { ths[i].sortFlag = -1; } } }
表格排序应用很常见,在面试中也会有这样的题目。这个小案例做下来,受益匪浅。这是我在学习的某峰学院的JS课程中的一个案例,如果对JS掌握不扎实的同学,欢迎保存:链接: https://pan.baidu.com/s/1jHVy8Uq 密码: v4jk
。如果链接失效,加Q群领取:154658901
。
Ich habe kürzlich das Sortieren von Tabellen in JS gelernt und nicht erwartet, dass das unauffällige Sortieren von Tabellen tatsächlich viele JS-Wissenspunkte impliziert. Zeichnen Sie diesen Lernprozess hier auf. Ich hoffe, es hilft auch allen.
Die vollständige Tabellensortierung umfasst die folgenden Wissenspunkte:
Aufrufmethode verwendet die
Sortiermethode im Detail
Datenbindung
DOM-Mapping
Im Folgenden werden diese Wissenspunkte detailliert zusammengefasst und schließlich kombiniert Wissenspunkte implementieren den folgenden Tabellensortierungsfall.
Vollständiger Fallquellcode: https://github.com/daweihe/JS...
Die Funktion der Aufrufmethode besteht darin, diesen Zeiger in der Methode zu ändern.
Aufruf Diese Methode ist in Function.prototype
definiert. Jede von uns definierte Funktion kann als Instanz der Klasse Function
betrachtet werden. Anschließend können Sie den Prototyp der Klasse über das Attribut __proto__
der Instanz finden. Jede Funktion kann Methoden wie call
und apply
aufrufen.
Schauen wir uns zunächst ein Beispiel an:
var obj = { name : 'JS' } function testCall () { console.log(this); } testCall.call( obj ); // {name: "JS"}
Zuerst findet die Funktion testCall
die Aufrufmethode über den Prototypketten-Suchmechanismus und führt sie während des Ausführungsprozesses aus Methode platziert die Aufrufmethode in der Funktionsinstanz. Dies wird in den ersten Parameter von Aufruf geändert, und dann wird die Instanzfunktion der Aufrufmethode aufgerufen und ausgeführt.
Sehen Sie sich zwei Fragen an:
function fn1() { console.log(1); console.log(this); } function fn2() { console.log(2); console.log(this); } fn1.call(fn2); //this -> fn2 fn1.call.call(fn2); //这里的call是改变function.__proto__.call的call方法中的this,相当于执行参数
Wenn die Aufrufmethode ausgeführt wird, wird der erste Parameter der Aufrufmethode verwendet, um dies zu ändern, und ab dem zweiten Parameter werden Parameter übergeben der Funktionsaufruf.
Wenn im nicht-strikten Modus keine Parameter an die Aufrufmethode übergeben werden oder null oder undefiniert übergeben wird, zeigt dies auf window
.
sum.call(); //window sum.call(null); //window sum.call(undefined); //window
Die Aufrufausführung im strikten Modus unterscheidet sich von der im nicht strikten Modus:
sum.call(); //undefined sum.call(null); //null sum.call(undefined); //undefined
Im Folgenden wird die Aufrufmethode verwendet, um eine Methode zum Konvertieren eines Klassenarrays zu implementieren ein Array:
function listToArray (likeAry) { var ary = []; try { ary = Array.prototype.slice.call(likeAry); } catch (e) { for (var i = 0; i < likeAry.length; i ++) { ary[ary.length] = likeAry[i]; } } return ary; }
Zu den Aufrufmethoden gehören die Apply- und Bind-Methoden. Hier ist eine kurze Zusammenfassung.
Die Apply-Methode funktioniert genauso wie die Call-Methode, außer dass die Form der Parameterübergabe unterschiedlich ist. Apply verpackt die Parameter der Funktion in ein Array:
function sum(num1, num2) { console.log(num2 + num1); console.log(this); } sum.apply(null,[100,200]);
Die Bindung Die Methode wird auch zum Ändern verwendet. Das Schlüsselwort this wird verwendet, aber es ändert nur den Sinn von this und führt nicht sofort die Funktion aus, die this aufruft.
function sum(num1, num2) { console.log(num2 + num1); console.log(this); } var obj = {name : 'zx'} var temp = sum.bind(obj); //temp已经是被改变了this的函数 temp(100,200); //当我们需要的时候才执行 //或者像这样处理 var temp = sum.bind(null, 100, 200); temp();
Bind-Methode verkörpert die Vorverarbeitungsidee in js.
Wir wissen, dass die sort
-Methode von Arrays nur Arrays innerhalb von 10 sortieren kann. Wenn das zu sortierende Array Zahlen größer als 10 enthält, müssen wir die Rückruffunktion an die sort
-Methode übergeben. Die übliche lautet wie folgt:
ary.sort(function (a,b) { return a - b; });
Auf diese Weise wird die Array kann in aufsteigender Reihenfolge sortiert werden. Was ist also das Prinzip dieser Sortierung?
Für die beiden übergebenen Parameter gilt: a
stellt das aktuelle Element im gefundenen Array dar und b
stellt das Element nach dem aktuellen Element dar.
return a -b
: Wenn a größer als b ist, wird das Ergebnis zurückgegeben und a und b tauschen die Positionen. Wenn a kleiner als b ist, bleiben die Positionen von a und b unverändert. Dies ist die aufsteigende Sortierung
return b -a
: Wenn b größer als a ist, wird das Ergebnis zurückgegeben und a und b tauschen die Positionen. Wenn a kleiner als b ist, bleiben die Positionen von a und b unverändert. Dies ist eine absteigende Reihenfolge
Wie sortiert man ein solches zweidimensionales Array nach Alter, nachdem man die Grundprinzipien verstanden hat?
var persons = [{ name:'dawei', age:55 },{ name:'ahung', age:3 },{ name:'maomi', age:2 },{ name:'heizi', age:78 },{ name:'afu', age:32 }];
Eigentlich ist es ganz einfach:
ary.sort(function(a,b){ return a.age - b.age; });
Wenn Sie nach Namen sortieren, ist die localeCompare()
-Methode der Zeichenfolge beteiligt:
ary.sort(function(a,b){ return a.name.localeCompare(b.name); });
name.localeCompare()
Diese Methode vergleicht die Buchstaben der beiden Zeichenfolgen unter den 24 englischen Buchstaben, wenn der erste Buchstabe der vorherigen Zeichenfolge früher erscheint als das erste Zeichen der zweiten Zeichenfolge. Geben Sie <🎜 zurück >. Wenn es später erscheint, wird die erste Zeichenfolge als größer betrachtet und 1 zurückgegeben. Wenn die verglichenen Zeichen gleich sind. Vergleichen Sie dann das nächste Zeichen. -1
//ary为需要添加到页面中的数据数组 var op = document.getElementById("box");//获取容器 var myUl = op.getElementsByTagName("ul")[0];//获取列表 var arrLength = ary.length; for (var i = 0;i < arrLength ; i ++) { //动态创建元素 var oli = document.createElement("li"); oli.innerHTML = '<span>' + (i + 5) + '</span>' + ary[i].title; myUl.appendChild(oli);//动态添加元素 }Jede Hinzufügung führt zu einem DOM-Reflow. Wenn die Datenmenge zu groß ist, beeinträchtigt dies die Leistung erheblich. Bezüglich DOM-Reflow und Neuzeichnen empfehle ich Ihnen, diesen Artikel zu lesen: http://www.css88.com/archives...Strings verbinden:
var str = ""; for(var i=0; i<ary.length; i++){ str += '<li>'; str += '<span>'; str += (i+5); str += '</span>'; str += ary[i].title; str += '</li>'; } myUl.innerHTML += str;Obwohl diese Methode nur einen Reflow verursacht, werden alle Ereignisse und Attribute aus den ursprünglichen Elementen entfernt. Wenn wir der Liste ein Ereignis für das li-Tag hinzufügen, wenn die Maus hinein bewegt wird und der Hintergrund seine Farbe ändert, macht diese Methode dieses Ereignis ungültig. Um die durch die beiden oben genannten Datenbindungsmethoden verursachten Probleme zu lösen, verwenden wir Dokumentfragmente zum Hinzufügen von Daten.
var frg = document.createDocumentFragment();//创建文档碎片 for (var i =0; i <ary.length ;i ++ ){ var li = document.createElement("li"); li.innerHTML = '<span>' + ( i + 5 ) + '</span>' + ary[i].title; frg.appendChild(li);//将数据动态添加至文档碎片中 } myUl.appendChild(frg); //将数据一次性添加到页面中 frg = null; //释放内存Dies führt nur einmal zu einem DOM-Reflow und behält die ursprünglich vorhandenen Ereignisse bei.
DOM映射机制:所谓映射,就是指两个元素集之间元素相互“对应”的关系。页面中的标签集合和在JS中获取到的元素对象(元素集合)就是这样的关系。如果页面中的HTML标签结构发送变化,那么集合中对应的内容也会跟着自动改变。
<ul id="myul"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> </ul>
对于这样一个列表使用下列脚本:
var myul = document.getElementById("myul"); var mylis = myul.getElementsByTagName('li'); for (var i = mylis.length - 1 ; i >= 0; i --) { myul.appendChild(mylis[i]); } console.log(mylis.length); // 5
将获取到的列表元素反序重新插入ul中,那么ul列表会变成下面这样:
<ul id="myul"> <li>5</li> <li>4</li> <li>3</li> <li>2</li> <li>1</li> </ul>
我们看到列表的长度依然是5,只是位置颠倒了。这是因为每个li标签和JS中获取的标签对象存在一个对应关系,当某个标签被重新插入到页面中时,页面中对应的标签会移动到插入的位置。这就是DOM映射。
之所以使用动态获取数据,是为了使用文档碎片绑定数据。
var res = ''; //声明一个全局变量,接收数据 var xhr = new XMLHttpRequest(); xhr.open('get', 'date.txt', false); xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { res = JSON.parse(xhr.responseText); } } xhr.send(null);
此时数据就保存在了res
这个全局变量之中。
var frg = document.createDocumentFragment(); for (let i = 0; i < res.length; i++) { var tr = document.createElement("tr"); for (key in res[i]) { var td = document.createElement("td"); td.innerHTML = res[i][key]; tr.appendChild(td); } frg.appendChild(tr); } tbody.appendChild(frg);
这里涉及的点较多
//为两列添加点击事件 for (let i = 0; i < ths.length; i++) { let curTh = ths[i]; curTh.sortFlag = -1; //用于对列进行升降序排列 curTh.index = i; //记录当前点击列的索引,便于排序操作 if (curTh.className == 'sort') { curTh.onclick = function() { sort.call(this); //改变排序函数内this的指向,让其指向当前点击列 } } } //排序方法 function sort() { //对数组元素进行排序 let target = this; //这里将this取出,因为在sort方法里需要使用该this,但是sort方法里的this是调用方法的数组 this.sortFlag *= -1; //1 代表升序 -1代表降序 let ary = listToArray(bodyTrs); //获取body数据 ary = ary.sort(function(a, b) { let one = a.cells[target.index].innerHTML; let two = b.cells[target.index].innerHTML; let oneNum = parseFloat(one); let twoNum = parseFloat(two); if (isNaN(oneNum) || isNaN(two)) { return one.localeCompare(two) * target.sortFlag; } else { return (oneNum - twoNum) * target.sortFlag; } }); //把排好序的数组重新写入页面 let frg = document.createDocumentFragment(); for (let i = 0; i < ary.length; i++) { rg.appendChild(ary[i]); } tbody.appendChild(frg); frg = null; //点击某列时,要将其他列的排序标志恢复为-1,让下次再点击任意一个标签时都是默认是升序排列 for (let i = 0; i < ths.length; i++) { if (ths[i] != this) { ths[i].sortFlag = -1; } } }
以上内容就是原生JS实现表格排序,希望能帮助到大家。
jquery中tablesorter表格排序组件是如何使用的?
js表格排序实例详解(支持int,float,date,string四种数据类型)
Das obige ist der detaillierte Inhalt vonNative JS implementiert die Tabellensortierung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!