最近在學習js的表格排序,沒想到看不起眼的表格排序其實卻隱含了眾多JS知識點。在這裡記錄一下此次學習過程。希望對大家也有幫助。
完整的表格排序涉及了下列這些知識點:
call方法使用
-
sort方法深入
資料綁定
DOM映射
下面詳細的總結一下這些知識點,最後結合這些知識點數實作下面這樣一個表格排序案例。
完整的案例原始碼:https://github.com/daweihe/JS...
一、知識點總結
1、call方法使用
call方法的作用是改變方法中的this指向。
call這個方法是定義在Function.prototype
的方法。我們定義的任何一個函數都可以認為它是Function
這個類別的一個實例。那就可以透過實例的__proto__
屬性來找到所屬類別的原型。任何一個函數都可以呼叫call
和apply
等方法。
先來看一個例子:
var obj = { name : 'JS' } function testCall () { console.log(this); } testCall.call( obj ); // {name: "JS"}
首先函數testCall
透過原型鏈尋找機制找到call方法執行,call方法在執行過程中把呼叫call方法這個函數實例中的this都改變成call的第一個參數,接下來呼叫call方法的這個實例函數執行。
看兩個題目:
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,相当于执行参数
call方法在執行的時候,call方法的第一個參數是用來改變this的,而從第二個參數開始都是傳給呼叫call的函數的參數。
在非嚴格模式下,給call方法不傳遞參數、或傳遞null、undefined後,this都是指向window
。
sum.call(); //window sum.call(null); //window sum.call(undefined); //window
嚴格模式下call執行的時候和非嚴格模式不同:
sum.call(); //undefined sum.call(null); //null sum.call(undefined); //undefined
下面使用call方法實作一個類別數組轉換為陣列的方法:
function listToArray (likeAry) { var ary = []; try { ary = Array.prototype.slice.call(likeAry); } catch (e) { for (var i = 0; i <p>和call類似的方法還有apply和bind方法,這裡簡單總結一下。 </p><p>apply方法的作用和call方法一模一樣,只是傳參的形式不太一樣,apply將函數的參數用數組包裹起來:</p><pre class="brush:php;toolbar:false">function sum(num1, num2) { console.log(num2 + num1); console.log(this); } sum.apply(null,[100,200]);
bind方法同樣也是用來改變this關鍵字的,但是它只是只改變this指向,不立即執行呼叫this的函數。
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方法體現了js中的預處理思想。
2、sort排序深入
我們知道陣列的sort
#方法只能排序10以內的陣列。如果需要排序的陣列中存在大於10的數字,我們就需要在sort
方法中傳入回呼函數,常見的是這樣:
ary.sort(function (a,b) { return a - b; });
這樣就能實現陣列的升序排序。那麼這樣排序的原理到底是什麼呢?
對於傳入的兩個參數:a
代表的是找到的陣列中的目前項,b
代表的是目前項的後一項。
return a -b
: 若a大於b,回傳結果,a與b交換位置。如果a小於b,那麼a和b位置不變。 這是升序排序return b -a
: 如果b大於a,回傳結果,a與b交換位置。如果a小於b,那麼a和b位置不變。 這是降序排序
了解了基本原理後,對於這樣一個二維數組,如何實現按年齡排序?
var persons = [{ name:'dawei', age:55 },{ name:'ahung', age:3 },{ name:'maomi', age:2 },{ name:'heizi', age:78 },{ name:'afu', age:32 }];
其實很簡單:
ary.sort(function(a,b){ return a.age - b.age; });
如果按姓名排序,則要涉及字串的localeCompare()
方法:
ary.sort(function(a,b){ return a.name.localeCompare(b.name); });
# name.localeCompare()
這個方法會根據兩個字串的字母進行比較,如果前一個字串的第一個字母在24個英文字母中出現的位置比後一個字串的第一個字符出現的位置靠前,則認定第一個字串小,傳回-1
。如果出現的位置靠後,則認定第一個字串大,回傳1。如果所比較的字元相等。則比較下一個字元。
這個方法很實用,常用於按姓氏排序,對於漢字,該方法會自動將漢字轉換為漢語拼音進行比較。
3、資料綁定
在js中一般使用動態綁定或拼接字串的方式實作資料綁定。
動態綁定:
//ary为需要添加到页面中的数据数组 var op = document.getElementById("box");//获取容器 var myUl = op.getElementsByTagName("ul")[0];//获取列表 var arrLength = ary.length; for (var i = 0;i ' + (i + 5) + '' + ary[i].title; myUl.appendChild(oli);//动态添加元素 }
每新增一次就會造成一次DOM回流,如果資料量過大,這樣會嚴重影響效能。
關於DOM的回流與重繪,推薦大家來看看這篇文章:http://www.css88.com/archives...
拼接字串:
var str = ""; for(var i=0; i<ary.length>'; str += '<span>'; str += (i+5); str += '</span>'; str += ary[i].title; str += ''; } myUl.innerHTML += str;</ary.length>
這種方式雖然只造成一次回流,但是它會去除原來存在的元素中所有的事件和屬性。如果我們為清單中的li標籤新增滑鼠移入,背景變色的事件,那麼這種方法會使這個事件失效。
為了解決上面的兩種資料綁定方法所帶來的問題,我們使用文件碎片來新增資料。
var frg = document.createDocumentFragment();//创建文档碎片 for (var i =0; i <ary.length>' + ( i + 5 ) + '' + ary[i].title; frg.appendChild(li);//将数据动态添加至文档碎片中 } myUl.appendChild(frg); //将数据一次性添加到页面中 frg = null; //释放内存</ary.length>
這樣即只引起一次DOM回流,又會保留原來存在的事件。
4、DOM映射
DOM映射机制:所谓映射,就是指两个元素集之间元素相互“对应”的关系。页面中的标签集合和在JS中获取到的元素对象(元素集合)就是这样的关系。如果页面中的HTML标签结构发送变化,那么集合中对应的内容也会跟着自动改变。
- 1
- 2
- 3
- 4
- 5
对于这样一个列表使用下列脚本:
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列表会变成下面这样:
- 5
- 4
- 3
- 2
- 1
我们看到列表的长度依然是5,只是位置颠倒了。这是因为每个li标签和JS中获取的标签对象存在一个对应关系,当某个标签被重新插入到页面中时,页面中对应的标签会移动到插入的位置。这就是DOM映射。
二、实现表格排序
1、使用ajax获取数据
之所以使用动态获取数据,是为了使用文档碎片绑定数据。
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
这个全局变量之中。
2、使用文档碎片绑定数据
var frg = document.createDocumentFragment(); for (let i = 0; i <h3 id="对表格进行排序">3、对表格进行排序</h3><p>这里涉及的点较多</p><pre class="brush:php;toolbar:false">//为两列添加点击事件 for (let i = 0; i <p>表格排序应用很常见,在面试中也会有这样的题目。这个小案例做下来,受益匪浅。这是我在学习的某峰学院的JS课程中的一个案例,如果对JS掌握不扎实的同学,欢迎保存:<code>链接: https://pan.baidu.com/s/1jHVy8Uq 密码: v4jk</code>。如果链接失效,加Q群领取:<code>154658901</code>。</p><p class="article fmt article__content"><br></p><p>最近在學習js的表格排序,沒想到看不起眼的表格排序其實卻隱含了眾多JS知識點。在這裡記錄一下此次學習過程。希望對大家也有幫助。 </p><p>完整的表格排序涉及了下列這些知識點:</p>
call方法使用
-
sort方法深入
資料綁定
DOM映射
下面詳細的總結一下這些知識點,最後結合這些知識點數實作下面這樣一個表格排序案例。
完整的案例原始碼:https://github.com/daweihe/JS...
一、知識點總結
1、call方法使用
call方法的作用是改變方法中的this指向。
call這個方法是定義在Function.prototype
的方法。我們定義的任何一個函數都可以認為它是Function
這個類別的一個實例。那就可以透過實例的__proto__
屬性來找到所屬類別的原型。任何一個函數都可以呼叫call
和apply
等方法。
先來看一個例子:
var obj = { name : 'JS' } function testCall () { console.log(this); } testCall.call( obj ); // {name: "JS"}
首先函數testCall
透過原型鏈尋找機制找到call方法執行,call方法在執行過程中把呼叫call方法這個函數實例中的this都改變成call的第一個參數,接下來呼叫call方法的這個實例函數執行。
看兩個題目:
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,相当于执行参数
call方法在執行的時候,call方法的第一個參數是用來改變this的,而從第二個參數開始都是傳給呼叫call的函數的參數。
在非嚴格模式下,給call方法不傳遞參數、或傳遞null、undefined後,this都是指向window
。
sum.call(); //window sum.call(null); //window sum.call(undefined); //window
嚴格模式下call執行的時候和非嚴格模式不同:
sum.call(); //undefined sum.call(null); //null sum.call(undefined); //undefined
下面使用call方法實作一個類別數組轉換為陣列的方法:
function listToArray (likeAry) { var ary = []; try { ary = Array.prototype.slice.call(likeAry); } catch (e) { for (var i = 0; i <p>和call類似的方法還有apply和bind方法,這裡簡單總結一下。 </p><p>apply方法的作用和call方法一模一樣,只是傳參的形式不太一樣,apply將函數的參數用數組包裹起來:</p><pre class="brush:php;toolbar:false">function sum(num1, num2) { console.log(num2 + num1); console.log(this); } sum.apply(null,[100,200]);
bind方法同樣也是用來改變this關鍵字的,但是它只是只改變this指向,不立即執行呼叫this的函數。
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方法體現了js中的預處理思想。
2、sort排序深入
我們知道陣列的sort
#方法只能排序10以內的陣列。如果需要排序的陣列中存在大於10的數字,我們就需要在sort
方法中傳入回呼函數,常見的是這樣:
ary.sort(function (a,b) { return a - b; });
這樣就能實現陣列的升序排序。那麼這樣排序的原理到底是什麼呢?
對於傳入的兩個參數:a
代表的是找到的陣列中的目前項,b
代表的是目前項的後一項。
return a -b
: 若a大於b,回傳結果,a與b交換位置。如果a小於b,那麼a和b位置不變。 這是升序排序return b -a
: 如果b大於a,回傳結果,a與b交換位置。如果a小於b,那麼a和b位置不變。 這是降序排序
了解了基本原理後,對於這樣一個二維數組,如何實現按年齡排序?
var persons = [{ name:'dawei', age:55 },{ name:'ahung', age:3 },{ name:'maomi', age:2 },{ name:'heizi', age:78 },{ name:'afu', age:32 }];
其實很簡單:
ary.sort(function(a,b){ return a.age - b.age; });
如果按姓名排序,則要涉及字串的localeCompare()
方法:
ary.sort(function(a,b){ return a.name.localeCompare(b.name); });
# name.localeCompare()
這個方法會根據兩個字串的字母進行比較,如果前一個字串的第一個字母在24個英文字母中出現的位置比後一個字串的第一個字符出現的位置靠前,則認定第一個字串小,傳回-1
。如果出現的位置靠後,則認定第一個字串大,回傳1。如果所比較的字元相等。則比較下一個字元。
這個方法很實用,常用於按姓氏排序,對於漢字,該方法會自動將漢字轉換為漢語拼音進行比較。
3、資料綁定
在js中一般使用動態綁定或拼接字串的方式實作資料綁定。
動態綁定:
//ary为需要添加到页面中的数据数组 var op = document.getElementById("box");//获取容器 var myUl = op.getElementsByTagName("ul")[0];//获取列表 var arrLength = ary.length; for (var i = 0;i ' + (i + 5) + '' + ary[i].title; myUl.appendChild(oli);//动态添加元素 }
每新增一次就會造成一次DOM回流,如果資料量過大,這樣會嚴重影響效能。
關於DOM的回流與重繪,推薦大家來看看這篇文章:http://www.css88.com/archives...
拼接字串:
var str = ""; for(var i=0; i<ary.length>'; str += '<span>'; str += (i+5); str += '</span>'; str += ary[i].title; str += ''; } myUl.innerHTML += str;</ary.length>
這種方式雖然只造成一次回流,但是它會去除原來存在的元素中所有的事件和屬性。如果我們為清單中的li標籤新增滑鼠移入,背景變色的事件,那麼這種方法會使這個事件失效。
為了解決上面的兩種資料綁定方法所帶來的問題,我們使用文件碎片來新增資料。
var frg = document.createDocumentFragment();//创建文档碎片 for (var i =0; i <ary.length>' + ( i + 5 ) + '' + ary[i].title; frg.appendChild(li);//将数据动态添加至文档碎片中 } myUl.appendChild(frg); //将数据一次性添加到页面中 frg = null; //释放内存</ary.length>
這樣即只引起一次DOM回流,又會保留原來存在的事件。
4、DOM映射
DOM映射机制:所谓映射,就是指两个元素集之间元素相互“对应”的关系。页面中的标签集合和在JS中获取到的元素对象(元素集合)就是这样的关系。如果页面中的HTML标签结构发送变化,那么集合中对应的内容也会跟着自动改变。
- 1
- 2
- 3
- 4
- 5
对于这样一个列表使用下列脚本:
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列表会变成下面这样:
- 5
- 4
- 3
- 2
- 1
我们看到列表的长度依然是5,只是位置颠倒了。这是因为每个li标签和JS中获取的标签对象存在一个对应关系,当某个标签被重新插入到页面中时,页面中对应的标签会移动到插入的位置。这就是DOM映射。
二、实现表格排序
1、使用ajax获取数据
之所以使用动态获取数据,是为了使用文档碎片绑定数据。
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
这个全局变量之中。
2、使用文档碎片绑定数据
var frg = document.createDocumentFragment(); for (let i = 0; i <h3 id="对表格进行排序">3、对表格进行排序</h3><p>这里涉及的点较多</p><pre class="brush:php;toolbar:false">//为两列添加点击事件 for (let i = 0; i <p>以上内容就是原生JS实现表格排序,希望能帮助到大家。</p><p><a href="http://www.php.cn/js-tutorial-371957.html" target="_self">js学习总结经典小案例之表格排序</a></p><p><a href="http://www.php.cn/js-tutorial-375121.html" target="_self">jquery中tablesorter表格排序组件是如何使用的?</a></p><p><a href="http://www.php.cn/js-tutorial-372544.html" target="_self">js表格排序实例详解(支持int,float,date,string四种数据类型)</a></p>
以上是原生JS實作表格排序的詳細內容。更多資訊請關注PHP中文網其他相關文章!

去掉重复并排序的方法:1、使用“Array.from(new Set(arr))”或者“[…new Set(arr)]”语句,去掉数组中的重复元素,返回去重后的新数组;2、利用sort()对去重数组进行排序,语法“去重数组.sort()”。

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于Symbol类型、隐藏属性及全局注册表的相关问题,包括了Symbol类型的描述、Symbol不会隐式转字符串等问题,下面一起来看一下,希望对大家有帮助。

怎么制作文字轮播与图片轮播?大家第一想到的是不是利用js,其实利用纯CSS也能实现文字轮播与图片轮播,下面来看看实现方法,希望对大家有所帮助!

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于对象的构造函数和new操作符,构造函数是所有对象的成员方法中,最早被调用的那个,下面一起来看一下吧,希望对大家有帮助。

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于面向对象的相关问题,包括了属性描述符、数据描述符、存取描述符等等内容,下面一起来看一下,希望对大家有帮助。

方法:1、利用“点击元素对象.unbind("click");”方法,该方法可以移除被选元素的事件处理程序;2、利用“点击元素对象.off("click");”方法,该方法可以移除通过on()方法添加的事件处理程序。

foreach不是es6的方法。foreach是es3中一个遍历数组的方法,可以调用数组的每个元素,并将元素传给回调函数进行处理,语法“array.forEach(function(当前元素,索引,数组){...})”;该方法不处理空数组。

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于BOM操作的相关问题,包括了window对象的常见事件、JavaScript执行机制等等相关内容,下面一起来看一下,希望对大家有帮助。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

SublimeText3漢化版
中文版,非常好用

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。