国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

案例學(xué)習(xí)總結(jié):原生JS實現(xiàn)表格排序

ShevaKuilin / 2038人閱讀

摘要:最近在學(xué)習(xí)的表格排序,沒想到看不起眼的表格排序?qū)嶋H上卻暗含了眾多知識點。二實現(xiàn)表格排序使用獲取數(shù)據(jù)之所以使用動態(tài)獲取數(shù)據(jù),是為了使用文檔碎片綁定數(shù)據(jù)。

最近在學(xué)習(xí)js的表格排序,沒想到看不起眼的表格排序?qū)嶋H上卻暗含了眾多JS知識點。在這里記錄一下此次學(xué)習(xí)過程。希望對大家也有所幫助。

完整的表格排序涉及了下列這些知識點:

call方法使用

sort方法深入

數(shù)據(jù)綁定

DOM映射

下面詳細(xì)的總結(jié)一下這些知識點,最后結(jié)合這些知識點實現(xiàn)下面這樣一個表格排序案例。

完整的案例源碼:https://github.com/daweihe/JS...

一、知識點總結(jié) 1、call方法使用

call方法的作用是改變方法中的this指向。

call這個方法是定義在Function.prototype的方法。我們定義的任何一個函數(shù)都可以認(rèn)為它是Function這個類的一個實例。那么就可以通過實例的__proto__屬性找到所屬類的原型。任何一個函數(shù)都可以調(diào)用callapply等方法。

先來看一個例子:

var obj = {
    name : "JS"
}

function testCall () {
    console.log(this);
}

testCall.call( obj );     // {name: "JS"}

首先函數(shù)testCall通過原型鏈查找機制找到call方法執(zhí)行,call方法在執(zhí)行過程中把調(diào)用call方法這個函數(shù)實例中的this都改變成call的第一個參數(shù),接下來調(diào)用call方法的這個實例函數(shù)執(zhí)行。

看兩個題目:

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,相當(dāng)于執(zhí)行參數(shù)

call方法在執(zhí)行的時候,call方法的第一個參數(shù)是用來改變this的,而從第二個參數(shù)開始都是傳給調(diào)用call的函數(shù)的參數(shù)。

在非嚴(yán)格模式下,給call方法不傳遞參數(shù)、或者傳遞null、undefined后,this都是指向window

sum.call(); //window
sum.call(null); //window
sum.call(undefined); //window

嚴(yán)格模式下call執(zhí)行的時候和非嚴(yán)格模式不同:

sum.call(); //undefined
sum.call(null); //null
sum.call(undefined); //undefined

下面使用call方法實現(xiàn)一個類數(shù)組轉(zhuǎn)換為數(shù)組的方法:

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;
}

和call類似的方法還有apply和bind方法,這里簡單總結(jié)一下。

apply方法的作用和call方法一模一樣,只是傳參的形式不太一樣,apply將函數(shù)的參數(shù)用數(shù)組包裹起來:

function sum(num1, num2) {
    console.log(num2 + num1);
    console.log(this);
}

sum.apply(null,[100,200]);

bind方法同樣也是用來改變this關(guān)鍵字的,但是它只是僅僅改變this指向,不立即執(zhí)行調(diào)用this的函數(shù)。

function sum(num1, num2) {
    console.log(num2 + num1);
    console.log(this);
}

var obj = {name : "zx"}

var temp = sum.bind(obj);   //temp已經(jīng)是被改變了this的函數(shù)
temp(100,200);              //當(dāng)我們需要的時候才執(zhí)行


//或者像這樣處理
var temp = sum.bind(null, 100, 200);
temp();

bind方法體現(xiàn)了js中的預(yù)處理思想。

2、 sort排序深入

我們知道數(shù)組的sort方法只能排序10以內(nèi)的數(shù)組。如果需要排序的數(shù)組中存在大于10的數(shù)字,我們就需要向sort方法中傳入回調(diào)函數(shù),常見的是這樣:

ary.sort(function (a,b) {
    return a - b;
}); 

這樣就能實現(xiàn)數(shù)組的升序排序。那么這樣排序的原理到底是什么呢?

對于傳入的兩個參數(shù):a代表的是找到的數(shù)組中的當(dāng)前項,b代表的是當(dāng)前項的后一項。

return a -b : 如果a大于b,返回結(jié)果,a與b交換位置。如果a小于b,那么a和b位置不變。 這是升序排序

return b -a : 如果b大于a,返回結(jié)果,a與b交換位置。如果a小于b,那么a和b位置不變。 這是降序排序

了解了基本原理后,對于這樣一個二維數(shù)組,如何實現(xiàn)按年齡排序?

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()這個方法會根據(jù)兩個字符串的字母進(jìn)行比較,如果前一個字符串的第一個字母在24個英文字母中出現(xiàn)的位置比后一個字符串的第一個字符出現(xiàn)的位置靠前,則認(rèn)定第一個字符串小,返回-1。如果出現(xiàn)的位置靠后,則認(rèn)定第一個字符串大,返回1。如果所比較的字符相等。則比較下一個字符。

這個方法很實用,常用于按姓氏排序,對于漢字,該方法會自動將漢字轉(zhuǎn)換為漢語拼音進(jìn)行比較。

3、數(shù)據(jù)綁定

在js中一般使用動態(tài)綁定或者拼接字符串的方式實現(xiàn)數(shù)據(jù)綁定。

動態(tài)綁定:

//ary為需要添加到頁面中的數(shù)據(jù)數(shù)組
var oDiv = document.getElementById("box");//獲取容器
var myUl = oDiv.getElementsByTagName("ul")[0];//獲取列表

var arrLength = ary.length;
for (var i = 0;i < arrLength ; i ++)
{  //動態(tài)創(chuàng)建元素
    var oli = document.createElement("li");
    oli.innerHTML = "" + (i + 5) + "" + ary[i].title;
    myUl.appendChild(oli);//動態(tài)添加元素
}

每添加一次就會引起一次DOM回流,如果數(shù)據(jù)量過大,這樣則會嚴(yán)重影響性能。

關(guān)于DOM的回流與重繪,推薦大家看一下這篇文章:http://www.css88.com/archives...

拼接字符串:

var str = "";
for(var i=0; i

這種方式雖然只引起一次回流,但是它會去除原來存在的元素中所有的事件和屬性。如果我們?yōu)榱斜碇械膌i標(biāo)簽添加鼠標(biāo)移入,背景變色的事件,那么這種方法會使這個事件失效。

為了解決上面的兩種數(shù)據(jù)綁定方法帶來的問題,我們使用文檔碎片來添加數(shù)據(jù)。

var frg = document.createDocumentFragment();//創(chuàng)建文檔碎片
for (var i =0; i " + ary[i].title;
    frg.appendChild(li);//將數(shù)據(jù)動態(tài)添加至文檔碎片中
}
myUl.appendChild(frg); //將數(shù)據(jù)一次性添加到頁面中
frg = null;  //釋放內(nèi)存

這樣即只引起一次DOM回流,又會保留原來存在的事件。

4、DOM映射

DOM映射機制:所謂映射,就是指兩個元素集之間元素相互“對應(yīng)”的關(guān)系。頁面中的標(biāo)簽集合和在JS中獲取到的元素對象(元素集合)就是這樣的關(guān)系。如果頁面中的HTML標(biāo)簽結(jié)構(gòu)發(fā)送變化,那么集合中對應(yīng)的內(nèi)容也會跟著自動改變。

  • 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標(biāo)簽和JS中獲取的標(biāo)簽對象存在一個對應(yīng)關(guān)系,當(dāng)某個標(biāo)簽被重新插入到頁面中時,頁面中對應(yīng)的標(biāo)簽會移動到插入的位置。這就是DOM映射。

二、實現(xiàn)表格排序 1、使用ajax獲取數(shù)據(jù)

之所以使用動態(tài)獲取數(shù)據(jù),是為了使用文檔碎片綁定數(shù)據(jù)。

var res = ""; //聲明一個全局變量,接收數(shù)據(jù)
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);

此時數(shù)據(jù)就保存在了res這個全局變量之中。

2、使用文檔碎片綁定數(shù)據(jù)
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);
3、對表格進(jìn)行排序

這里涉及的點較多

//為兩列添加點擊事件
for (let i = 0; i < ths.length; i++) {
    let curTh = ths[i];
    curTh.sortFlag = -1; //用于對列進(jìn)行升降序排列
    curTh.index = i; //記錄當(dāng)前點擊列的索引,便于排序操作
    if (curTh.className == "sort") {
        curTh.onclick = function() {
            sort.call(this); //改變排序函數(shù)內(nèi)this的指向,讓其指向當(dāng)前點擊列
        }
    }
}


//排序方法
function sort() {
    //對數(shù)組元素進(jìn)行排序
    let target = this; //這里將this取出,因為在sort方法里需要使用該this,但是sort方法里的this是調(diào)用方法的數(shù)組
    this.sortFlag *= -1; //1 代表升序   -1代表降序
    let ary = listToArray(bodyTrs); //獲取body數(shù)據(jù)
    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;
        }
    });
    //把排好序的數(shù)組重新寫入頁面
    let frg = document.createDocumentFragment();
    for (let i = 0; i < ary.length; i++) {
        rg.appendChild(ary[i]);
    }
    tbody.appendChild(frg);
    frg = null;

    //點擊某列時,要將其他列的排序標(biāo)志恢復(fù)為-1,讓下次再點擊任意一個標(biāo)簽時都是默認(rèn)是升序排列
    for (let i = 0; i < ths.length; i++) {
        if (ths[i] != this) {
            ths[i].sortFlag = -1;
        }
    }
}

表格排序應(yīng)用很常見,在面試中也會有這樣的題目。這個小案例做下來,受益匪淺。這是我在學(xué)習(xí)的某峰學(xué)院的JS課程中的一個案例,如果對JS掌握不扎實的同學(xué),歡迎保存:鏈接: https://pan.baidu.com/s/1jHVy8Uq 密碼: v4jk。如果鏈接失效,加Q群領(lǐng)取:154658901

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/112840.html

相關(guān)文章

  • 案例學(xué)習(xí)總結(jié)原生JS實現(xiàn)表格排序

    摘要:最近在學(xué)習(xí)的表格排序,沒想到看不起眼的表格排序?qū)嶋H上卻暗含了眾多知識點。二實現(xiàn)表格排序使用獲取數(shù)據(jù)之所以使用動態(tài)獲取數(shù)據(jù),是為了使用文檔碎片綁定數(shù)據(jù)。 最近在學(xué)習(xí)js的表格排序,沒想到看不起眼的表格排序?qū)嶋H上卻暗含了眾多JS知識點。在這里記錄一下此次學(xué)習(xí)過程。希望對大家也有所幫助。 完整的表格排序涉及了下列這些知識點: call方法使用 sort方法深入 數(shù)據(jù)綁定 DOM映射 下面...

    lauren_liuling 評論0 收藏0
  • 【連載】前端個人文章整理-從基礎(chǔ)到入門

    摘要:個人前端文章整理從最開始萌生寫文章的想法,到著手開始寫,再到現(xiàn)在已經(jīng)一年的時間了,由于工作比較忙,更新緩慢,后面還是會繼更新,現(xiàn)將已經(jīng)寫好的文章整理一個目錄,方便更多的小伙伴去學(xué)習(xí)。 showImg(https://segmentfault.com/img/remote/1460000017490740?w=1920&h=1080); 個人前端文章整理 從最開始萌生寫文章的想法,到著手...

    madthumb 評論0 收藏0
  • 原生Js-msi系統(tǒng)

    摘要:我也意識到在學(xué)習(xí)一個框架前,將框架的思想和原生的實現(xiàn)進(jìn)行對比有多么重要。這個是目前為止一個大的框架思路,當(dāng)然還要再進(jìn)行每個功能的細(xì)分。表格將上一步的并集數(shù)據(jù)顯示出來渲染分表格,表格有一個表頭,用于展示商品的種類地區(qū)以及每月的銷售情況。 前言:由于剛?cè)肭岸藭r間并不長,之前最近一直處在學(xué)習(xí)的階段,現(xiàn)在準(zhǔn)備找工作,回首看看之前學(xué)的,發(fā)現(xiàn)了很多的瑕疵。我分析覺得主要原因在于之前有些東西學(xué)的太快...

    K_B_Z 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<