由數(shù)據(jù)綁定和排序引入的幾個(gè)JavaScript知識(shí)點(diǎn)

一织阳、sort深入

這次我們要完成一個(gè)表格排序的案例咳短,那說到排序填帽,最終肯定是歸結(jié)于數(shù)組的排序。對(duì)于數(shù)組的排序咙好,我們最先想到的肯定是sort方法篡腌,所以我們深入了解一下sort。

1.1勾效、基本排序

定義數(shù)組:

var ary = [22, 3, 14, 12, 23, 1, 48];

在mdn中對(duì)sort的定義如下:

arr.sort(compareFunction)
compareFunction:可選嘹悼。用來指定按某種順序進(jìn)行排列的函數(shù)。如果省略层宫,元素按照轉(zhuǎn)換為的字符串的諸個(gè)字符的Unicode位點(diǎn)進(jìn)行排序杨伙。

從mdn的描述中可以看出,如果沒有指定一個(gè)函數(shù)作為參數(shù)萌腿,那么只能比較10以內(nèi)的數(shù)字缀台,所以一般都會(huì)指定一個(gè)函數(shù)作為參數(shù)。

在compareFunction中可以傳入兩個(gè)參數(shù)假定為a哮奇、b,這兩個(gè)參數(shù)即為待比較多兩個(gè)數(shù):

  • a:每一次執(zhí)行匿名函數(shù)的時(shí)候睛约,找到的數(shù)組中的當(dāng)前項(xiàng)鼎俘;
  • b:當(dāng)前項(xiàng)的后一項(xiàng)

compareFunction的返回值則為一個(gè)數(shù)字,如果返回值大于0辩涝,則讓a和b交換一下位置贸伐,如果返回值小于等于0,原來的位置不動(dòng)怔揩。

在本例中:

  • 如果:return a - b捉邢,表示升序排序脯丝,如果a大于b,返回值大于0伏伐,a和b交換位置宠进,輸出的結(jié)果為:[1, 3, 12, 14, 22, 23, 48]

  • 如果:return b - a藐翎,表示降序排序材蹬,如果b大于a,返回值大于0吝镣,a和b交換位置堤器,輸出的結(jié)果為:[48, 23, 22, 14, 12, 3, 1]

1.2末贾、對(duì)象數(shù)組(二維數(shù)組)排序

定義對(duì)象數(shù)組:

var ary = [
    {name: 'iceman', age: 25},
    {name: 'mengzhe', age: 13},
    {name: 'shoushou', age: 107},
    {name: 'jiajia', age: 256}
];

對(duì)象數(shù)組的排序闸溃,正常情況都是要求根據(jù)某個(gè)值為數(shù)字的屬性來排序,在本例中拱撵,我們要求以年齡來排序辉川。

sort方法的參數(shù)compareFunction的參數(shù)中兩個(gè)參數(shù),并一定就一定是要數(shù)字裕膀,這兩個(gè)參數(shù)是數(shù)組中的某一項(xiàng)员串,注意是數(shù)組中的某一項(xiàng)哦!也就是說在對(duì)象數(shù)組中昼扛,這兩個(gè)參數(shù)代表的是一個(gè)對(duì)象寸齐。在得到了這個(gè)結(jié)論之后,我們就可以根據(jù)通過對(duì)象的屬性來排序了:

ary.sort(function (a, b) {
    return parseFloat(a.age) - parseFloat(b.age);
});
console.log(ary);
對(duì)象數(shù)組排序后的結(jié)果.png

二抄谐、json

現(xiàn)在與服務(wù)端的交互中一般都是使用json渺鹦,應(yīng)該基本被使用xml了,我是做Android開發(fā)的蛹含,在我開始做Android的時(shí)候就是使用json毅厚,所以json也是現(xiàn)在主流的一種數(shù)據(jù)交互格式。浦箱。

可能很多人會(huì)將json歸結(jié)于一種新的數(shù)據(jù)類型吸耿,其實(shí)并不是這樣的,json只是一種特殊的數(shù)據(jù)格式酷窥,歸根結(jié)底json還是對(duì)象數(shù)據(jù)類型的咽安。比如,

普通格式的對(duì)象如下:

var obj = {name:'iceman' , age:7};

json格式對(duì)象如下:

var jsonObj = {"name":"iceman" , "age":7};

相對(duì)于普通格式的對(duì)象來說蓬推,json對(duì)象只是把屬性名用雙引號(hào)包起來了妆棒。

在window瀏覽器對(duì)象中,提供了一個(gè)叫做JSON的屬性(window.JSON),它里面提供了兩個(gè)方法:

  • JSON.parse :把JSON格式的字符串糕珊,轉(zhuǎn)換為JSON格式的對(duì)象动分;
  • JSON.stringify :把JSON格式的對(duì)象,轉(zhuǎn)換為JSON格式的字符串红选;
var jsonObj = {"name":"iceman" , "age":7};
var jsonStr = JSON.stringify(jsonObj); // --> 字符串
console.log(jsonStr);

var str = '{"name":"iceman" , "age":7}';
console.log(JSON.parse(str));

注意: 在IE6~7中澜公,window下沒有JSON屬性,所以parse和stringify方法都不存在了纠脾,那么這時(shí)候要把JSON格式的字符串轉(zhuǎn)換為JSON格式的對(duì)象可以使用eval方法:

var str = '{"name":"iceman" , "age":7}';
eval("(" + str + ")");

使用eval裝好JSON格式的對(duì)象玛瘸,一定要手動(dòng)加一個(gè)小括號(hào)。

二苟蹈、數(shù)據(jù)綁定

2.1糊渊、準(zhǔn)備JSON格式的數(shù)據(jù)

var ary = [
    {
        "title": "11111",
        "desc": "aaaaaaaa"
    },
    {
        "title": "22222",
        "desc": "bbbbbbbb"
    }
  ......
];

2.2、頁面結(jié)構(gòu)

<ul id="ul1">
    <li>原來就有的慧脱,這里有鼠標(biāo)的移入移出事件</li>
</ul>
body, ul, li {margin: 0; padding: 0; list-style: none;}
#ul1 {margin: 10px auto; padding: 10px; width: 300px; border:1px solid #008000;  }
#ul1 li {position: relative; padding-left: 28px;  height:35px; line-height: 35px; text-overflow: ellipsis; white-space: nowrap; overflow: hidden;  }
#ul1 li span { display: block; position: absolute;  top: 6px;  left: 0;  width: 21px;  height: 21px;  line-height: 20px;  text-align: center;  border: 1px solid #ccc;  font-size: 12px;  border-radius: 50%;  }

尋找元素以及添加移入移出事件:

var oUl = document.getElementById('ul1');
var oLis = oUl.getElementsByTagName('li');

for (var i = 0; i < oLis.length; i++) {
    oLis[i].onmouseover = function () {
        this.style.backgroundColor = 'pink';
    };
    oLis[i].onmouseout = function () {
        this.style.backgroundColor = '';
    };
}

2.3渺绒、DOM深入:重繪與回流

  • 回流(也叫重排):當(dāng)頁面中的HTML結(jié)構(gòu)發(fā)生改變(增加、刪除元素菱鸥、位置發(fā)生改變...)宗兼,瀏覽器都需要重新計(jì)算一遍最新的DOM結(jié)構(gòu),重新對(duì)當(dāng)前的頁面進(jìn)行渲染氮采;

  • 重繪:某一個(gè)元素的部分樣式發(fā)生改變了(背景顏色殷绍、字號(hào)等),瀏覽器只需要重新渲染當(dāng)前頁面即可鹊漠;

2.4主到、動(dòng)態(tài)創(chuàng)建節(jié)點(diǎn)再追加到頁面的方式實(shí)現(xiàn)數(shù)據(jù)綁定

for (var i = 0; i < ary.length; i++) {
    var cur = ary[i];
    var oLi = document.createElement('li');
    oLi.innerHTML = '<span>' + i + '</span>' + cur.title + '---' + cur.desc;
    oUl.appendChild(oLi);
}

優(yōu)勢(shì): 把需要?jiǎng)討B(tài)綁定的內(nèi)容一個(gè)個(gè)追加到頁面中,對(duì)原來的元素沒有任何的影響躯概;

缺點(diǎn):每當(dāng)創(chuàng)建一個(gè)li登钥,就添加到頁面中,會(huì)引發(fā)一次DOM回流最后引發(fā)回流的次數(shù)過多娶靡,影響性能牧牢。

2.5、字符串拼接的方式實(shí)現(xiàn)數(shù)據(jù)綁定

var str = "";
for (var i = 0; i < ary.length; i++) {
    var cur = ary[i];
    str += '<li>';
    str += '<span>' + i + '</span>';
    str += cur.title;
    str += '</li>'
}
oUl.innerHTML += str;

首先循環(huán)需要綁定的數(shù)據(jù)姿锭,然后把需要?jiǎng)討B(tài)綁定的標(biāo)簽以字符串的方式拼接到一起塔鳍,拼接完成最后統(tǒng)一添加到頁面中。

拼接完成的整體還是字符串呻此,最后把字符串統(tǒng)一的添加到頁面中轮纫,瀏覽器還需要把字符串渲染成最新的標(biāo)簽。

字符串拼接綁定數(shù)據(jù)趾诗,使以后工作中最常用的一種綁定數(shù)據(jù)的方式,因?yàn)樗心0逡娴臄?shù)據(jù)綁定(jade、kTemplate....)以及所有的框架(angular.js恃泪、backbone.js....)的原理都是字符串拼接郑兴,所以說你可能沒有自己直接使用字符串拼接,但是在使用引擎以及框架的過程已經(jīng)用到了贝乎。

** 優(yōu)勢(shì):** 事先把內(nèi)容拼接好情连,最后統(tǒng)一添加到頁面中,只引發(fā)一次回流览效;

缺點(diǎn): 把新拼接的字符串添加到#ul1中却舀,原有的三個(gè)li的鼠標(biāo)滑過效果都消失了(原來標(biāo)簽綁定的事件都消失了)。

2.6锤灿、文檔碎片的方式實(shí)現(xiàn)數(shù)據(jù)綁定

var frg = document.createDocumentFragment(); // 創(chuàng)建一個(gè)文檔碎片挽拔,相當(dāng)于臨時(shí)創(chuàng)建了一個(gè)容器
for (var i = 0; i < ary.length; i++) {
    var cur = ary[i];
    var oLi = document.createElement('li');
    oLi.innerHTML = '<span>' + i + '</span>' + cur.title;
    frg.appendChild(oLi);
}
oUl.appendChild(frg);
frg = null;

這種方式解決了以上的問題,但是實(shí)際開發(fā)中用的很少但校。

三螃诅、表格排序

<ul id="ul1">
    <li>98</li>
    <li>99</li>
    <li>96</li>
    <li>95</li>
    <li>90</li>
</ul>
var utils = {
    listToArray:function (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;
    }
};
var oUl = document.getElementById('ul1');
var oLis = oUl.getElementsByTagName('li');

// 1、先把元素集合類數(shù)組轉(zhuǎn)換為數(shù)組
var ary = utils.listToArray(oLis);

// 2状囱、給數(shù)組進(jìn)行排序:按照每一個(gè)li中的內(nèi)容大小進(jìn)行排序
ary.sort(function (a, b) {
    return parseFloat(a.innerHTML) - parseFloat(b.innerHTML);
});

// 3术裸、按照ary中存儲(chǔ)的最新順序,依次的把對(duì)應(yīng)的li添加到頁面當(dāng)中
var frg = document.createDocumentFragment();
for (var i = 0; i < ary.length; i++) {
    var obj = ary[i];
    frg.appendChild(obj);
}
oUl.appendChild(frg);
frg = null;

DOM映射機(jī)制:頁面中的標(biāo)簽和JavaScript中獲取到的元素對(duì)象或者元素集合是緊緊綁定在一起的亭枷,也中的HTML結(jié)構(gòu)改變了袭艺,JS中不需要重新獲取,集合里面的內(nèi)容也會(huì)跟著自動(dòng)改變叨粘。

var oUl = document.getElementById('ul1');
var oLis = oUl.getElementsByTagName('li');
console.log(oLis.length); // 5

var oLi = document.createElement('li');
oUl.appendChild(oLi);
console.log(oLis.length); // 6猾编,沒有重新的獲取,但是oLis這個(gè)集合中的長(zhǎng)度和內(nèi)容會(huì)自動(dòng)跟著發(fā)生改變

個(gè)人公眾號(hào)(icemanFE):分享更多的前端技術(shù)和生活感悟

個(gè)人公眾號(hào).png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末宣鄙,一起剝皮案震驚了整個(gè)濱河市袍镀,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌冻晤,老刑警劉巖苇羡,帶你破解...
    沈念sama閱讀 210,914評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異鼻弧,居然都是意外死亡设江,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門攘轩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來叉存,“玉大人,你說我怎么就攤上這事度帮〖吣螅” “怎么了稿存?”我有些...
    開封第一講書人閱讀 156,531評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)瞳秽。 經(jīng)常有香客問我瓣履,道長(zhǎng),這世上最難降的妖魔是什么练俐? 我笑而不...
    開封第一講書人閱讀 56,309評(píng)論 1 282
  • 正文 為了忘掉前任袖迎,我火速辦了婚禮,結(jié)果婚禮上腺晾,老公的妹妹穿的比我還像新娘燕锥。我一直安慰自己,他們只是感情好悯蝉,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
  • 文/花漫 我一把揭開白布归形。 她就那樣靜靜地躺著,像睡著了一般泉粉。 火紅的嫁衣襯著肌膚如雪连霉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,730評(píng)論 1 289
  • 那天嗡靡,我揣著相機(jī)與錄音跺撼,去河邊找鬼。 笑死讨彼,一個(gè)胖子當(dāng)著我的面吹牛歉井,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播哈误,決...
    沈念sama閱讀 38,882評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼哩至,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了蜜自?” 一聲冷哼從身側(cè)響起菩貌,我...
    開封第一講書人閱讀 37,643評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎重荠,沒想到半個(gè)月后箭阶,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,095評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡戈鲁,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
  • 正文 我和宋清朗相戀三年仇参,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片婆殿。...
    茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡诈乒,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出婆芦,到底是詐尸還是另有隱情怕磨,我是刑警寧澤喂饥,帶...
    沈念sama閱讀 34,253評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站肠鲫,受9級(jí)特大地震影響仰泻,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜滩届,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望被啼。 院中可真熱鬧帜消,春花似錦、人聲如沸浓体。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽命浴。三九已至娄猫,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間生闲,已是汗流浹背媳溺。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評(píng)論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留碍讯,地道東北人悬蔽。 一個(gè)月前我還...
    沈念sama閱讀 46,248評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像捉兴,于是被迫代替她去往敵國和親蝎困。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理倍啥,服務(wù)發(fā)現(xiàn)禾乘,斷路器,智...
    卡卡羅2017閱讀 134,626評(píng)論 18 139
  • 第5章 引用類型(返回首頁) 本章內(nèi)容 使用對(duì)象 創(chuàng)建并操作數(shù)組 理解基本的JavaScript類型 使用基本類型...
    大學(xué)一百閱讀 3,216評(píng)論 0 4
  • 自己的思維積累才是學(xué)霸養(yǎng)成的過程中最重要的步驟 就像通往財(cái)富自由之路中的注意力的重要程度一樣虽缕,不同于時(shí)間始藕、不同于金...
    晨聽閱讀 985評(píng)論 0 8
  • 問:請(qǐng)教一下老師,為什么都在說加息就意味著通脹要來了,這兩者是怎樣的邏輯關(guān)系.通脹要來,怎么黃金還一直跌.還有人說...
    ad5e912c526b閱讀 454評(píng)論 0 0
  • 再相遇鳄虱,你平淡如水,我亦云淡風(fēng)輕凭峡。再交心拙已,你輕描淡寫,我亦含語不言摧冀。再牽手倍踪,你相安無事系宫,我亦重頭來過。
    葉初夏薔薇閱讀 182評(píng)論 0 0