1. 程式人生 > >JQuery與原生JS的那點事--選擇器

JQuery與原生JS的那點事--選擇器

JQuery與原生JS的那點事–選擇器

為什麼jquery這麼火

    1、在瀏覽器群雄割據的年代,各種不相容。(Jquery2.0以上版本不支援ie6、7、8)
    2、輕量級。你要想想前端的程式碼多是要通過網路請求下來,雖然有快取,但是程式碼越少越節約網路請求的時間。
    3、各種方便的api。
    4、健壯的外掛庫。

    JQuery的地位,就連比較牛的Angular框架多要內建一個jqlite。我們需要學習JQuery,但是我們要在學習JQuery的同時,理解原生的JS,這才是王道。

    下面的例子多是基於JQuery(v3.1.1)

$()返回的是什麼型別

    技巧:Object.prototype.toString.call()

    $()始終返回的多是[object Object]
    而對於原生的方法中多個元素返回[object NodeList](NodeList不是陣列)
    如果是單個元素則返回[HTMLXXXXElement]

$()的容錯功能

    比如:$('.some').css('height','200px')如果.some不存在,這句程式碼並不會報錯。
    原生的document.querySelector('.some').style.height="200px",就會報錯。

    仔細想想,誰又會傻到查詢一個不存在的dom呢,假如你寫錯了(這是不是一個很牽強的理由),但是有一種情況是避免不了的,動態的dom.
    所以那時候我們只能這樣寫:
    var
some = document.querySelector('.some'); if(some) { some.style.height = "200px"; } 雖然原生麻煩,但是卻在警示每個開發人員要以嚴謹的態度去寫程式碼。

JQ查詢方法與原生查詢方法的對比

    --------------
      JQuery
    --------------  
    $(str) 是不是比較容易記。

    --------------
      原生JS
    --------------  
    document.querySelector() 返回的是單個元素 不相容ie6、7.
    document.querySelectorAll() 返回的NodeList 不相容ie6、7.
    document.getElementById() 返回的是單個元素

    (還有其他的我就不介紹了,上面的已經夠用了,如果非要糾結ie6、7,那就用JQuery吧)
    這裡query兩個方法與$(str)幾乎沒什麼差別。但是這裡要特別主要應為這些方法多是要對字串解析的,所以你的字串越複雜,函式執行的效率越低,所以要注意方法的結合使用與你html程式碼的合理編寫。
    也正是應為如此,jquery也提供很多減輕選擇器過於複雜的方法。
    下面我會針對各種選擇器列出(JQuery,JS,CSS)三種寫法
    (CSS的部分寫法,可能相容性上有點問題)
    (要通過JQuery來複習JS,是多麼慚愧的一件事。)

選擇器

    -------------
      元素選擇器
    -------------
    栗子:使li的背景顏色變成紅色
    JQ:
    $('li').css('background','red')
    JS: 這裡為了省事 就用了map(相容性有點問題-_-!)
    Array.prototype.map.call(document.querySelectorAll('li'),function(item){
        item.style.background = "red";
    })
    CSS:
    li {
        background-color: red;
    }


    ---------------
      類選擇器
    ---------------
    栗子:使類名為some的背景顏色變成紅色
    JQ:
    $('.some').css('background','red')
    JS:這裡我們預設只有一個some類(換一種寫法-_-)
    document.querySelector('.some').style.background="red"
    CSS:
    .some {
        background-color: red;
    }


    ------------
      ID選擇器
    ------------
    栗子: 使ID為box的元素的背景顏色改為紅色
    JQ:
    $('#box').css('background','red')
    JS:
    document.getElementById('box').style.background="red"
    CSS:
    #box {
        background-color: red;
    }
    這裡有個細節,JQ和JS對於ID的查詢預設是唯一的,但是我在頁面中宣告兩個一樣的ID並不會報錯,而在CSS中設定ID的樣式,並不會考慮到唯一性。
    所以這裡開發者應該多要遵循ID唯一的原則,避免造成不必要的錯誤。


    ---------------
      群組選擇器
    ---------------
    栗子: 使ul和div的背景顏色變成紅色
    JQ:
    $('ul,div').css('background','red')
    JS: (上面提到map的相容性,所以我還是擴充套件NodeList的原型方法吧^-^。)
    NodeList.prototype.map = function(callback){
        for(var i = 0; i < this.length; i++) {
            //改變this指向
            callback.call(this[i]);
        }
    }
    document.querySelectorAll('li,div').map(function(){
        this.style.background = "red";
    });
    CSS:
    ul,div {
        background-color: red;
    }


    ----------------
      後代選擇器
    ----------------
    栗子: 使ul下面所有的li的背景顏色變成紅色(這裡要與繼承區別開)
    JQ:
    $('ul li').css('background','red');

    通過上面幾個例子,JS和CSS的寫法我就不寫了。


    -------------
      兒子選擇器
    -------------
    栗子: 使ID為box的ul下的li的背景顏色變成紅色,而li裡面巢狀的ul的li不受影響(排除繼承)
    JQ:
    $('#box>li').css('background','red')
    提供了children([selector])的方法,最好的寫法
    $("#box").children().css('background','red');

    這裡要特別注意,JS是不提供鏈式呼叫的,千萬別這樣寫:
    document.getElementById('box').querySelectorAll('li')這是錯的。


    -------------------
      A + B
    -------------------
    栗子: 找出與A同級的後一位為B的元素的背景顏色變成紅色
    JQ:
    $('.p1 + div').css('background','red');
    提供了next(selector)的方法,最好的寫法
    $('.p1').next('div').css('background','red');

    ----------------
      A ~ B
    ----------------
    栗子: 找出與A同級的後面所有的B元素的背景顏色變成紅色
    JQ:
    $('.p1 ~ p').css('background','red');
    同樣有nextAll(selector)
    $('.p1').nextAll('p').css('background','red');


    -----------------
      .a.b
    -----------------
    同時滿足擁有.a.b類名的
    JQ:
    $('.p1.dai').css('background','red');


    舉了這幾個例子,套路大家應該多懂了吧,還有很多選擇器,大家去看看文件吧,畢竟文件才是王道。
    再嘮叨幾句屬性選擇器:
    = 等於
    != 不等於
    ^= 以什麼開頭
    $= 以什麼結尾
    ~= 以空格間隔的值列表
    *= 含有子串

    還有一些特別容易出錯的地方
    :even是從0開始的 :nth-child()是從1開始的
    :parent含有子元素的元素 :empty沒有子元素(文字節點也算)
    但是parent()確是找到父元素。。
    end()返回到上一個狀態

這幾個JQuery特有的方法還是挺重要的

    ------------------
      prev與prevAll
    ------------------
    這個找一個節點的同級節點的前面的一個節點或者是所有節點
    JQ:
    $('.p1').prev('p').css('background','red');
    $('.p1').prevAll('p').css('background','red');


    -------------
      siblings
    -------------
    查詢兄弟節點
    $('.p1').siblings('p').css('background','red');


    ---------------------------
      nextUntil與prevUntil
    ---------------------------
    nextUntil(selector): 往一個節點的同級節點的前面查詢,直到selector停止。
    prevUntil(selector):