對dom元素進行排序的研究

對dom元素進行排序的研究

今天在看dom元素的排序,有一個題目如下:

<!—— HTML結構 ——>

   
           
  • JavaScript
  •        
  • Python
  •        
  • Swift
  •    

需求:除了列出的3種語言外,請再按上面的結構新增Pascal、Lua和Ruby,然後按字母順序排序節點

即最終的效果如下:

   
           
  • JavaScript
  •        
  • Lua
  •        
  • Pascal
  •        
  • Python
  •        
  • Ruby
  •        
  • Swift
  •    

大部分人的思路是先把每一行的字串提取出來,然後排序,排序之後再把之前的節點刪除,然後新建節點,加上相應的標籤。程式碼如下:

//需要匯入jquery包//獲取span標籤,並轉換為陣列,Array。from()可以將其他物件轉換為陣列li=Array。from($(“#test-div>ul>li>span”))//獲取span標籤內的文字val=li。map(x=>x。innerHTML)//新增三個語言val。push(“Pascal”)val。push(“Lua”)val。push(“Ruby”)//新增完後,val是[‘JavaScript’,‘Lua’,‘Pascal’,‘Pascal’,‘Lua’,‘Ruby’]//進行排序,排序後val為[“JavaScript”, “Lua”, “Pascal”, “Python”, “Ruby”, “Swift”]val。sort()//刪除所有li節點$(“#test-div>ul>li”)。remove()//使用模板字串將新節點加入到ul節點中val。map(x=>$(“#test-div>ul”)。append(`

  • ${x}
  • `))

    這樣做確實簡單,它相當於把原來的節點刪除後,重新新建節點,並將排好序的節點加入原來的父節點。

    但是它並不是將原來的節點排序,這時我在想,可不可以直接對節點進行排序呢?sort方法不是可以直接排序的嗎?於是翻看sort方法介紹:

    // 傳兩個形參當返回值為正數時,交換傳入兩形參在陣列中位置    // sort()如果不帶引數,是將按字母順序對陣列中的元素進行排序,也就是是按照字元編碼的順序進行排序。    // 對字串的排序    var arr1 = [‘adfa’, ‘dad’, ‘cad’, ‘bfdf’];    arr1。sort();  //[‘a’, ‘b’, ‘c’, ‘d’]    // 對數字的排序    var arr2 = [10, 5, 40, 25, 100, 1];    arr2。sort(); //[1, 10 ,100, 25, 40, 5]    /* 由於排序是按ASCII的順序來排序的,所以這裡對數字排序後得不到想要的結果   從左到右依次比較ASCII碼值,所以結果是[1, 10 ,100, 25, 40, 5]   同樣的,字串的比較也是按這個原則,如:   */    console。log(“a”<“b”);//true    console。log(“abc”<“aad”);//false,    /* 當數字是按字母順序排列時“40”將排在“5”前面。使用數字排序,你必須透過一個   函式作為引數來呼叫。函式指定數字是按照升序還是降序排列。需要傳入引數。   排序函式規則:   傳兩個形參   當返回值為正數時,交換傳入兩形參在陣列中位置   */    arr2。sort(function(a,b){return a-b})    //可以使用箭頭函式簡寫為    arr2。sort((a,b)=>a-b)    //如果是倒序    arr2。sort((a,b)=>b-a)    console。log(arr1,arr2)    // 如果是物件    var arr3 = [       {name:‘zopp’,age:0},       {name:‘gpp’,age:18},       {name:‘yjj’,age:8}   ];    //按年齡從小到大排序    arr3。sort((a,b)=>{        return a。age-b。age;        // return b。age-a。age; //按年齡從大到小排序   })    arr3。forEach(item=>document。write(JSON。stringify(item)))    //{“name”:“zopp”,“age”:0}{“name”:“yjj”,“age”:8}{“name”:“gpp”,“age”:18}

    但是如果物件按字串來排序呢?介紹裡沒有寫。但是研究了一下

    arr3。sort((a,b)=>{     return a。name-b。name; })

    按上面的寫法,得不到想要的結果,這裡就要回顧下字串比較大小的規則了:

    字串排序是按ASCII的順序來排序的,從左到右依次比較ASCII碼值,例如:

    console。log(“a”<“b”);//trueconsole。log(“abc”<“aad”);//false,

    這裡再回頭想想sort()的返回值,應該是一個數字,而不是字串,如果是正數,則是正序,負數則為倒序,0則不變,這裡把sort修改下:

    arr3。sort((a,b)=>{    //注意:字串比較應該使用>,<,==,而不是-號    return (a。name===b。name)? 0 : (a。name>b。name)?1:-1;})arr3。forEach(item=>document。write(JSON。stringify(item)))

    這樣就得到了滿意的結果。

    回到最初的題目,那麼可以得到程式碼如下:

       
             
    • JavaScript
    •        
    • Python
    •        
    • Swift
    •    
    <!——為了加強演示效果,加兩個按鈕——>

    js

    部分如下:

    function addDom() {    var ul = $(“#test-div ul”)    // 按結構新增三種語言    ul。append(“

  • Pascal
  • ”)    ul。append(“
  • Lua
  • ”)    ul。append(“
  • Ruby
  • ”)}function sortDom() {    var ul = $(“#test-div ul”)    //將新增節點後的物件轉換為陣列    lisArr = Array。from(ul。find(“li”))    lisArr。forEach(item => console。log(item。innerText))    //對li節點按節點中的字串排序(正序)    var newArr = lisArr。sort((a, b) => {        return (a。innerText === b。innerText) ? 0 : (a。innerText > b。innerText) ? 1 : -1   })    console。log(“——————————-”)    newArr。forEach(item => console。log(item。innerText))    /* 將排序好的節點加入ul中,由於newArr是一個數組,不能直接新增,要先轉換為jquery物件   對於已經存在的節點,會直接替換原來的節點,所以不需要再刪除原來的節點 */    ul。append($(newArr))}

    完整程式碼:

    <!DOCTYPE html>        修改dom    <!—— HTML結構 ——>

       
             
    • JavaScript
    •        
    • Python
    •        
    • Swift
    •    
    <!——為了加強演示效果,加兩個按鈕——>