jQuery面試知識點整理

落木蕭蕭下發表於2018-05-30

一、基礎

(1)jQuery有哪些優點?

  1. 輕量級(3.2.1.min只有85kb左右)
  2. 強大的選擇器(css1到css3以及jQuery獨創)
  3. 出色的DOM操作封裝
  4. 可靠的事件處理機制($(document).ready())
  5. 完善的Ajax
  6. 不汙染全域性變數,對外只暴露一個jQuery($)物件
  7. 出色的相容性(IE6.0+)
  8. 鏈式操作(return this)
  9. 隱式迭代
  10. 行為層和結構層分離
  11. 豐富的外掛
  12. 開源

(2)jQuery物件和DOM物件如何轉換?

  • DOM轉為jQuery物件:
    var $btn = $'('#btn'); // jQuery物件
  • jQuery物件轉為DOM物件
// 方式一
var btn = $btn[0];  // DOM物件
// 方式二
var btn = $btn.get(0);  // DOM物件
複製程式碼

(3)如何判斷一個元素是否存在?

// 方式一,通過長度判斷
if ($('.link').length > 0) {}

// 方式二,轉為DOM物件
if ($('.link')[0]) {}
複製程式碼

注意:不能直接通過$('.link')來判斷,$('.link')永遠是物件。

// 錯誤方式
if ($('.link')) {}
複製程式碼

二、選擇器

(1)jQuery的選擇器有哪些?

  • 基本選擇器
  1. $('#id')
  2. $('.class')
  3. $('element')
  4. $('*')
  5. $('selector1,selector2,....')
  • 層次選擇器
  1. $('ancestor descendant') 後代選擇器
  2. $('parent>child') 子選擇器
  3. $('prev+next') 相鄰兄弟選擇器
$('.one+div') === $('.one').next('div')
複製程式碼
  1. $('prev~siblings') prev元素之後的所有兄弟元素(siblings()與前後位置無關,能選擇到所有兄弟元素)
$('#prev~div') === $('#prev').nextAll('div')
複製程式碼
  • 過濾選擇器 (以 : 開頭,屬性過濾除外)
  1. 基本過濾
1. $('div:first')  // 第一個元素  優先使用$('div').first()
2. $('div:last')  // 最後一個元素  優先使用$('div').last()
3. $('input:not(#submit)')  // 去除匹配的元素
4. $('input:even')  // 偶數的input
5. $('input:odd')  // 奇數的input
6. $('input:eq(1)')  // 索引等於1的input  優先使用$('input').eq(1)  從0開始
7. $('input:gt(1)')  // 索引大於而不包括1的input
8. $('input:lt(1)')  // 索引小於而不包括1的input
9. $(':header')  // h1到h6的所有元素
10.$('div:animated')   // 正在執行動畫的div
11. $(':focus')  // 當前獲得焦點的元素
複製程式碼
  1. 內容過濾
1. $("div:cotains('hello world')")  // 包含hello world文字的div元素
2. $('div:empty')  // 不含子元素和文字的空元素
3. $('div:has(p)')  // 含有p元素的div元素
4. $('div:parent')  // 擁有子元素或文字的div元素
複製程式碼
  1. 可見性過濾
1. $(':hidden')  // 所有不可見元素,包括<input type='hidden' /> 、 display:none 
2. $(':visible')  // 所有可見的元素
複製程式碼
  1. 屬性過濾
1. $('div[id]')  // 擁有id屬性的div元素
2. $('div[title=test]')  // title屬性為test的div元素
3. $('div[title!=test]')  // title屬性不等於test(沒有title屬性)的div元素
4. $('div[title^=test]')  // title屬性以test開始的div元素
5. $('div[title$=test]')  // title屬性以test結束的div元素
6. $('div[title*=test]')  // title屬性包含test的div元素
7.$('div[title|="en"]')  // title屬性等於en或以en為字首(en-mytitle)的div元素
8. $('div[title~="en"]')  // title屬性用空格分隔的值中含有字元en的div元素
9. $('div[id=btn][title^=test]')  // id屬性等於btn並且title屬性以test開始的div元素
複製程式碼
  1. 子元素過濾
1. nth-child(index/even/odd/equation)  // index從1開始
$('ul li:nth-child(2)')  // ul下的第二個li元素
2. $('ul li:first-child')  // 為每個父元素ul匹配第一個li元素 ($('ul li:first')只匹配第一個ul的第一個li元素)
3. $('ul li:last-child')  // 為每個父元素ul匹配最後一個li元素 ($('ul li:last')只匹配第一個ul的最後一個li元素)
4. $('ul li:only-child')  // ul中只有一個li時,才選擇li元素
複製程式碼
  1. 表單物件過濾
1. $('#form1 :enabled')  // id屬性為form1的表單內的所有可用的元素
2. $('#form1 :disabled')  // id屬性為form1的表單內的所有不可用的元素
3. $('input:checked')  // 所有被選中的input元素
4. $('select option:selected')  // 所有被選中的選項元素
複製程式碼
  • 表單選擇器
    根據type屬性選擇
1. $(':input')  // 所有input、textarea、select、button
2. $(':text')  // 所有<input type='text' />
3. $(':password')  // 所有<input type='password' />
4. $(':radio')  // 所有<input type='radio' />
5. $(':checkbox')  // 所有<input type='checkbox' />
6. $(':submit')  // 所有<button type='submit'></button>
7. $(':image')  // 所有<button type='image'></button>
8. $(':reset')  // 所有<button type='reset'></button>
9. $(':file')  // 所有<input type='file' />
10. $(':hidden')  // 所有不可見的元素
11. $(':button')  // 所有<button></button>
複製程式碼

==選擇器注意事項:==

  1. 選擇器中含有 '.'、 '#'、 '()' 、 '[]' 需要轉義
<div id='id#my'></div>
<div id='id[8]'></div>

$('#id\\#my')  
$('#id\\[8\\]')
複製程式碼
  1. 選擇器中的空格,有空格是後代選擇器

(2)jQuery中如何優化選擇器效能?

  1. 儘量使用css中有的選擇器
  2. 避免過度約束 ($('div ul li a')與$('li a'))
  3. 儘量以id開頭
  4. 讓選擇器右邊有更多特徵
  5. 避免使用全域性選擇器
  6. 快取選擇結果

三、DOM操作

(1)jQuery中如何查詢節點?

  1. 元素節點(選擇器)
<button id='btn' type='submit'>登入</button>
var $btn = $('#btn');
複製程式碼
  1. 屬性節點(attr())
var type = $btn.attr('type');   // submit
複製程式碼
  1. 文字節點(text())
var text = $btn.text()  // 登入
複製程式碼

(2)jQuery中如何建立節點

元素節點、屬性節點、文字節點可以同時建立

var $li = $('<li title=蘋果'>蘋果</li>);
複製程式碼

(3)jQuery中如何插入節點?

  • 作為子元素插入
  1. append()
<p>I want to say</p>
$('p').append('<b>hello</b>')
// 結果
<p>I want to say<b>hello</b></p>
複製程式碼
  1. appendTo()
<p>I want to say</p>
$('<b>hello</b>').appendTo('p')
// 結果
<p>I want to say<b>hello</b></p>
複製程式碼
  1. prepend()
<p>I want to say</p>
$('p').prepend('<b>hello</b>')
// 結果
<p><b>hello</b>I want to say</p>
複製程式碼
  1. prependTo()
<p>I want to say</p>
$('<b>hello</b>').prependTo('p')
// 結果
<p><b>hello</b>I want to say</p>
複製程式碼
  • 作為兄弟元素插入
  1. after()
<p>I want to say</p>
$('p').after('<b>hello</b>')
// 結果
<p>I want to say</p><b>hello</b>
複製程式碼
  1. insertAfter()
<p>I want to say</p>
$('<b>hello</b>').insertAfter('p')
// 結果
<p>I want to say</p><b>hello</b>
複製程式碼
  1. before()
<p>I want to say</p>
$('p').before('<b>hello</b>')
// 結果
<b>hello</b><p>I want to say</p>
複製程式碼
  1. insertAfter()
<p>I want to say</p>
$('<b>hello</b>').insertBefore('p')
// 結果
<b>hello</b><p>I want to say</p>
複製程式碼

(4)jQuery中如何刪除節點?

  1. remove()
var $li = $('ul li').eq(1).remove() // 所有後代都會被刪除,返回值是刪除節點的引用。remove('選擇器')也可以傳參
$li.appendTo('ul')  // 刪除的節點可以重新新增回來

$('ul li').eq(1).appendTo('ul')  // 移動選擇的元素到最後
複製程式碼
  1. detach()
    和remove() 幾乎一樣,不同的是detach()所繫結的事件、附加的資料都會保留。(重新新增後事件和資料還在)
  2. empty()
    並不刪除節點,只是清空所有後代元素。

(5)jQuery中如何複製節點?

clone()

$('ul li').click(function() {
    $(this).clone(true).appendTo('ul')  // 複製並新增到ul中,引數true表示同時複製繫結的事件
})
複製程式碼

(6)jQuery中如何替換元素?

  1. replaceWith()
<p>你想去哪兒?</p>
$('p').replaceWith('<p>你想幹什麼?</p>')
// 結果
<p>你想幹什麼?</p>
複製程式碼
  1. replaceAll()
<p>你想去哪兒?</p>
$('<p>你想幹什麼?</p>').replaceAll('p')
// 結果
<p>你想幹什麼?</p>
複製程式碼

(7)jQuery中如何包裹節點?

  1. wrap()
$('p').wrap('<strong></strong>')  // 對每個p標籤單獨用strong標籤包裹
複製程式碼
  1. wrapAll()
$('p').wrapAll('<strong></strong>')  // 對所有p標籤用一個strong標籤包裹
複製程式碼
  1. wrapInner()
$('p').wrapInner('<strong></strong>')  // 對每個p標籤的子內容用strong標籤包裹
複製程式碼

(8)jQuery中如何操作屬性?

  1. attr()
vat title = $('ul li').eq(0).attr('title')  // 獲取匹配元素的title屬性

$('ul li').eq(0).attr({id:'apple', title='蘋果'})  // 設定匹配元素的屬性
複製程式碼
  1. removeAttr()
$('ul li').eq(0).removeAttr('title')  // 刪除匹配元素指定的屬性
複製程式碼
  1. prop() 用法同上
  2. removeProp() 用法同上

(9)jQuery中如何操作樣式?

  1. addClass() 追加樣式類名 $('p').addClass('mystyle') // 多次使用類名疊加
  2. attr() $('p').attr('class', 'mystyle') // 多次使用後面覆蓋前面的
  3. removeClass() 刪除所有或指定類名
  4. toggleClass() 重複切換類名(存在就刪除,不存在就新增)
  5. hasClass() 判斷是否含有某個類名
  6. css() 獲取或設定樣式 包括外部匯入
  7. width() (content區域)
  8. height()
  9. innerWidth() (包含padding)
  10. innerHeight()
  11. outerWidth() (包含border,傳入true包含margin)
  12. outerHeight()
  • 元素定位有關的方法
  1. offset() 元素相對於視窗的偏移,包含top、left屬性
  2. position() 元素相對於最近的定位元素的偏移,包含top、left屬性
  3. scrollTop() 獲取或設定滾動條距頂端的距離
  4. scrollLeft() 獲取或設定滾動條距左端的距離

(10)jQuery中如何獲取和設定html、文字、值?

  1. html()
  2. text()
  3. val()

(11)jQuery中如何遍歷節點?

  1. children()
  2. next()
  3. prev()
  4. siblings()
  5. closest()
  6. parent()
  7. parents()
  8. find()
  9. filter()
  10. nextAll()
  11. prevAll()

四、事件和動畫

(1)window.onload()與$(document).ready()(簡寫$(function{}))的區別?

  1. 執行時機不同:
  • window.onload()在所有內容(js、css、image等)載入完成後執行。
  • $(document).ready()在DOM結構載入完成後就會執行。
  1. 使用次數
  • window.onload()只能執行一次,如果使用多次,後面覆蓋前面的。
  • $(document).ready()可以使用多次,按順序執行。

(2)如何繫結事件?

  1. on(type[,selector][,data], fn)
    off() 刪除事件
$('#btn').on('click', function() {
    console.log($(this).val())
})

// 簡寫方式
$('#btn').click(function() {
    console.log($(this).val())
})
複製程式碼
  1. one() 事件執行一次後就刪除

(3)合成事件有哪些?

  1. hover(enter, leave) 游標進入和離開
$('#btn').hover(function(){
    $(this).next().show()  // 游標進入觸發
}, function() {
     $(this).next().hide()  // 游標離開觸發
})
複製程式碼
  1. toggle(speed[,callback]) 切換元素可見狀態
$('#btn').click(function() {
    $(this).next().toggle(200) 
}
複製程式碼

(4)事件物件的屬性有哪些?

  1. event.type 獲取事件型別
  2. event.preventDefautl() 阻止預設行為
  3. event.stopPropagation() 阻止冒泡 (return false 可以同時阻止預設行為和冒泡)
  4. event.target 目標元素
  5. event.relatedTarget 相關目標元素(mouseenter、mouseleave、mouseout、mouseover、focus、blur事件有相關目標元素)
  6. event.pageX 、 pageY 游標相對於頁面的xy座標
  7. event.which 滑鼠單擊事件中獲取滑鼠的左(1)、中(2)、右(3)鍵
  8. event.metaKey 獲取windows中win鍵(Mac中Cmd鍵)是否被按下

(5)trigger()與triggerHandler()的作用與區別?

  • 作用:都是用來觸發事件的
    $('#btn').trigger('click') 這樣不用點選就觸發了點選事件
  • 區別:
  1. triggerHandler() 不執行瀏覽器預設行為
  2. triggerHandler() 不會冒泡
  3. triggerHandler() 只觸發集合中的第一個
  4. 返回的是函式處理後的值,不是jQuery物件
  5. 不能使用鏈式(因為第4點)

(6)jQuery中內建動畫有哪些?

  • 基本動畫
  1. show(speed[,callback]) 和 hide(speed[,callback]) 顯示隱藏元素
    所有動畫的speed:number、fast(200)、normal(400)、slow(600)
$('#btn').toggle(function() {
    $(this).next().show() // 顯示
}, function() {
    $(this).next().hide() // 隱藏 display:none(隱藏之前會記住display屬性的值)
})
複製程式碼

==注意:== 1.9以上的版本以不再支援toggle(fn1,fn2) 模擬滑鼠連續單擊事件

  • ==解決方案==:指令碼中加入以下程式碼,作為外掛
$.fn.toggle = function( fn, fn2 ) {
    var args = arguments,guid = fn.guid || $.guid++,i=0,
    toggle = function( event ) {
        var lastToggle = ( $._data( this, "lastToggle" + fn.guid ) || 0 ) % i;
         $._data( this, "lastToggle" + fn.guid, lastToggle + 1 );
        event.preventDefault();
        return args[ lastToggle ].apply( this, arguments ) || false;
    };
    toggle.guid = guid;
    while ( i < args.length ) {
        args[ i++ ].guid = guid;
    }
    return this.click( toggle );
  };
複製程式碼
  1. fadeIn(speed[,callback]) 和 fadeOut(speed[,callback]) 淡入淡出(改變opacity)
$('#btn').toggle(function() {
    $(this).next().fadeIn() // 淡入
}, function() {
    $(this).next().fadeOut() // 淡出  display:none
})
複製程式碼
  1. slideUp(speed[,callback]) 和 slideDown(speed[,callback])
    改變元素高度
$('#btn').toggle(function() {
    $(this).next().slideUp() 
}, function() {
    $(this).next().slideDown() // display:none
})
複製程式碼
  • 自定義動畫
  1. animate()
    animate(params, speed, callback)
    params是一個包含樣式屬性及值的對映
// html
<div id='mydiv'></div>

// css
#mydiv {
   position: relative;
   width: 100px;
   height: 100px;
   background: #eee;
   border: 1px solid #ccc;
   cursor: pointer;
}

// script
$('#mydiv').click(function() {
    $(this).animate({left: '600px', height: 200px, opacity: 0.5},3000)  
        .animate({top: '200px', width: 200px},2000)  // 前一個animate執行完了才執行
        .fadeOut(400)  // 前一個animate執行完了才執行
        // 形成一個動畫佇列
})
複製程式碼
  • 動畫回撥函式
    ==非動畫方法不會加入動畫佇列中,可以在回撥函式裡實現對非動畫方法排隊==
$('#mydiv').click(function() {
    $(this).animate({left: '600px', height: 200px, opacity: 0.5},3000)  
        .animate({top: '200px', width: 200px},2000)  // 前一個animate執行完了才執行
        .css({
            border: '3px solid red'
        })  // 動畫一開始執行 css()就會執行
})

// 解決方案: 回撥函式
$('#mydiv').click(function() {
    $(this).animate({left: '600px', height: 200px, opacity: 0.5},3000)  
        .animate({top: '200px', width: 200px},2000, function() {
            $(this)..css({
                border: '3px solid red'
            })  // 動畫執行完了才會執行 css()
        }) 
        
})
複製程式碼
  • 停止動畫
    stop(clearQueue, gotoEnd)
    clearQueue(布林值)表示是否要清空未執行的動畫佇列
    gotoEnd (布林值)表示是否直接將正在執行的動畫跳到末狀態
// 直接呼叫 stop()停止當前正在執行的動畫,立即進入動畫佇列的下一個動畫
$('#div1').hover(function() {
    $(this).stop()
        .animate({height: '300px', width: '300px'}, 500)
}, function() {
     $(this).stop()
        .animate({height: '100px', width: '100px'}, 300)
})

// 當遇到組合動畫時,stop()需要傳入引數
$('#div1').hover(function() {
    $(this).stop(true)  // true 清空未執行的動畫佇列
        .animate({height: '300px', width: '300px'}, 500)
        .animate({color: 'red', opacity: 0.5}, 200)
}, function() {
     $(this).stop(true)  // true 清空未執行的動畫佇列
        .animate({height: '100px', width: '100px'}, 300)
        .animate({color: 'green', opacity: 1}, 200)
})
複製程式碼
  • ==判斷元素是否處於動畫狀態==(重要)
    避免出現動畫積累
if (! $('#div1').is(':animated')) { 
    // 沒有處於動畫狀態才新增動畫
}
複製程式碼
  • 動畫延遲
    delay(time)

  • 互動動畫

  1. toggle(speed[,callback])
    切換元素可見狀態
$('#div1').click(function() {
    $(this).next().toggle()  // 相當於前面基本動畫的第一個
})
複製程式碼
  1. slideToggle(speed[,easing][,callback])
    通過高度切換元素可見狀態
$('#div1').click(function() {
    $(this).next().sildeToggle()  // 相當於前面基本動畫的第二個
})
複製程式碼
  1. fadeTo(speed[,opacity][,callback])
    把opacity以漸進的方式調到指定值
$('#div1').click(function() {
    $(this).next().fadeTo(600, 0.5)  // 600ms內opacity調到 0.5
})
複製程式碼
  1. fadeToggle(speed[,easing][,callback])
    通過高度切換元素可見狀態
$('#div1').click(function() {
    $(this).next().fadeToggle()  // 相當於前面基本動畫的第三個
})
複製程式碼

五、Ajax

(1)jQuery中封裝了哪些ajax方法,分別在什麼情況下使用?

  • 底層方法
  1. $.ajax()
    用途:可以實現以下所有方法,當需要定製更多資訊時使用此方法(例如timeout、beforeSend、error、global等)
    $.ajax(options)
    options常用引數:
options = {
    url: 請求的地址 (String),
    type: 請求方式 (Strin),
    timeout: 請求超時時間的毫秒數(Number),
    data: 傳送的資料(Object、String),
    dataType: 期待伺服器返回的資料型別(String),
    beforeSend: 傳送前的回撥函式可以修改XMLHttpRequest物件,return false可以取消本次請求,function(XMLHttpRequest){this // 呼叫本次options引數}。(Function),
    complete: 請求完成回撥函式,無論成功還是失敗,function(XMLHttpRequest, textStatus) {this // 呼叫本次options引數}。(Function),
    success: 請求成功回撥函式,function(data, textStatus) {this // 呼叫本次options引數} (Function),
    error:  請求失敗回撥函式,function(XMLHttpRequest, textStatus, errorThrown) {this // 呼叫本次options引數} (Function),
    global: 是否要觸發全域性ajax事件,預設true (Boolean)
}
複製程式碼
  • 快捷方法
  1. load() (ajax方法中唯一一個非全域性函式)
  • 用途:載入或篩選HTML文件,並插入DOM中。
    $('selecotr').load('url selector' [,data] [,function(responseText,textStatus,XMLHtmlRequest) {}]) 回撥函式請求完成時執行,無論成功還是失敗。textStatus:success、error、notmodified、timeout 4種
$('#send').click(function() {
    $('#container').load('test.html .link')  
}) // 請求test.html,並從中篩選含有link類名的標籤返回,返回後插入到id為container的標籤中。
複製程式碼
  • 傳參
    load()沒有引數使用GET方法,有引數時自動轉換為POST方法
// 自動使用 POST 方法
 $('#container').load('test.php', {name: 'xiaoming', age: 22}, callback)  
複製程式碼
  1. $.get()
    用途:傳送GET請求。
    $.get(url [,data] [,function(data, textStatus) {}] [,type])
    只有當請求成功時(success)才執行回撥函式,並把結果和狀態專入回撥函式。
    type表示期待伺服器返回的格式:xml、html、script、json、text等
$('#send').click(function() {
    var username = $('#username').val();
    $.get('test.php', {username: username}, function(data, textStatus) {
        var username = data.username;
        var content = data.content;
        var html = '<div><h5>' + username + ':</h5><p>' + content + '</p></div>';
        $('#container').html(html);
    }, 'json');
});
複製程式碼
  1. $.post()
    用途:傳送POST請求。
    $.post(url [,data] [,function(data, textStatus) {}] [,type]) 與$.get()方法的結構和使用方式相同。
  • 與$.get()方法的區別:
  1. GET請求將引數追加在URL後面進行傳遞,POST請求將引數作為Http實體內容傳遞,對使用者不可見。
  2. GET請求對傳輸的資料大小有限制,一般2KB,POST請求理論上沒有限制,比GET請求大得多。
  3. GET請求安全性較低,POST請求安全性較高。
$('#send').click(function() {
    var username = $('#username').val();
    $.post('test.php', {username: username}, function(data, textStatus) {
        var username = data.username;
        var content = data.content;
        var html = '<div><h5>' + username + ':</h5><p>' + content + '</p></div>';
        $('#container').html(html);
    }, 'json');
});
複製程式碼
  1. $.getScript()
    用途:載入js檔案。
$.getScript(url [,callback])
複製程式碼
  1. $.getJSON()
    用途:載入JSON檔案。$.getScript(url [,function(data){}])
$('#send').click(function() {
    $.getJSON('test.json', function(data) {
        $.each(data, function(index, item) {
            // 遍歷 data
        });
    });
});
複製程式碼

(2)jQuery中有哪些ajax全域性事件?

  1. ajaxStart(callback) 請求開始時觸發
  2. ajaxStop(callback) 請求結束時觸發
  3. ajaxComplete(callback) 請求完成時觸發
  4. ajaxSuccess(callback) 請求成功時觸發
  5. ajaxError(callback) 請求失敗時觸發
  6. ajaxSend(callback) 請求傳送前觸發

(3)jQuery中如何序列化元素?

  1. serialize()
    將匹配的元素內容序列化
$.get('test.php', $(#form1).serialize(), function(data, textStatus) {})
複製程式碼
  1. serializeArray()
    將匹配元素的值編譯成擁有name和value物件組成的陣列
var fields = $(':checkbox,:radio').serializeAray()
複製程式碼
  1. $.param()
    全域性函式,用來對一個陣列或物件按照key/value的形式進行序列化。
var obj = {a: 1, b:2, c:3};
var result = $.param(obj);  // a=1&b=2&c=3
複製程式碼

六、外掛

(1)有哪些常用外掛?

  1. Validation 表單驗證
  2. jQuery Form 表單外掛
  3. SimpleModal 模態視窗
  4. Cookie cookie外掛
  5. jQuery UI

(2)jQuery外掛的種類有哪些?

  1. 物件方法 (大多數)
(function($) {
    $.fn.pluginName = function() {
        // 外掛
        return this;  // 使外掛可以鏈式操作
    }
})(jQuery)
複製程式碼
  1. 全域性函式
(function($) {
    $.pluginName = function() {
        // 外掛
    }
})(jQuery)
複製程式碼
  1. 選擇器

七、效能優化

(1)jQuery中可以做哪些效能優化?

  1. 使用合適的選擇器
  2. 快取物件
  3. 迴圈操作DOM時,儘可能減少DOM操作(插入20個節點,應該建立好後一次性插入)
  4. 使用事件代理
  5. 封裝成外掛
  6. 壓縮程式碼

相關文章