阅读 1274

jQuery面试知识点整理

一、基础

(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. 压缩代码
文章分类
前端