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

資訊專(zhuān)欄INFORMATION COLUMN

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

lauren_liuling / 2732人閱讀

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

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

完整的表格排序涉及了下列這些知識(shí)點(diǎn):

call方法使用

sort方法深入

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

DOM映射

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

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

一、知識(shí)點(diǎn)總結(jié) 1、call方法使用

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

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

先來(lái)看一個(gè)例子:

var obj = {
    name : "JS"
}

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

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

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

看兩個(gè)題目:

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í)行的時(shí)候,call方法的第一個(gè)參數(shù)是用來(lái)改變this的,而從第二個(gè)參數(shù)開(kāi)始都是傳給調(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í)行的時(shí)候和非嚴(yán)格模式不同:

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

下面使用call方法實(shí)現(xiàn)一個(gè)類(lèi)數(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類(lèi)似的方法還有apply和bind方法,這里簡(jiǎn)單總結(jié)一下。

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

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

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

bind方法同樣也是用來(lái)改變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)我們需要的時(shí)候才執(zhí)行


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

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

2、 sort排序深入

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

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

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

對(duì)于傳入的兩個(gè)參數(shù):a代表的是找到的數(shù)組中的當(dāng)前項(xiàng),b代表的是當(dāng)前項(xiàng)的后一項(xià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位置不變。 這是降序排序

了解了基本原理后,對(duì)于這樣一個(gè)二維數(shù)組,如何實(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
}];

其實(shí)很簡(jiǎn)單:

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

如果按姓名排序,則要涉及字符串的localeCompare()方法:

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

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

這個(gè)方法很實(shí)用,常用于按姓氏排序,對(duì)于漢字,該方法會(huì)自動(dòng)將漢字轉(zhuǎn)換為漢語(yǔ)拼音進(jìn)行比較。

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

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

動(dòng)態(tài)綁定:

//ary為需要添加到頁(yè)面中的數(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 ++)
{  //動(dòng)態(tài)創(chuàng)建元素
    var oli = document.createElement("li");
    oli.innerHTML = "" + (i + 5) + "" + ary[i].title;
    myUl.appendChild(oli);//動(dòng)態(tài)添加元素
}

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

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

拼接字符串:

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

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

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

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

這樣即只引起一次DOM回流,又會(huì)保留原來(lái)存在的事件。

4、DOM映射

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

  • 1
  • 2
  • 3
  • 4
  • 5

對(duì)于這樣一個(gè)列表使用下列腳本:

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列表會(huì)變成下面這樣:

  • 5
  • 4
  • 3
  • 2
  • 1

我們看到列表的長(zhǎng)度依然是5,只是位置顛倒了。這是因?yàn)槊總€(gè)li標(biāo)簽和JS中獲取的標(biāo)簽對(duì)象存在一個(gè)對(duì)應(yīng)關(guān)系,當(dāng)某個(gè)標(biāo)簽被重新插入到頁(yè)面中時(shí),頁(yè)面中對(duì)應(yīng)的標(biāo)簽會(huì)移動(dòng)到插入的位置。這就是DOM映射。

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

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

var res = ""; //聲明一個(gè)全局變量,接收數(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í)數(shù)據(jù)就保存在了res這個(gè)全局變量之中。

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、對(duì)表格進(jìn)行排序

這里涉及的點(diǎn)較多

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


//排序方法
function sort() {
    //對(duì)數(shù)組元素進(jìn)行排序
    let target = this; //這里將this取出,因?yàn)樵趕ort方法里需要使用該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ù)組重新寫(xiě)入頁(yè)面
    let frg = document.createDocumentFragment();
    for (let i = 0; i < ary.length; i++) {
        rg.appendChild(ary[i]);
    }
    tbody.appendChild(frg);
    frg = null;

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

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

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/90221.html

相關(guān)文章

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

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

    ShevaKuilin 評(píng)論0 收藏0
  • 【連載】前端個(gè)人文章整理-從基礎(chǔ)到入門(mén)

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

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

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

    K_B_Z 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<