jQuery
jquery 特点,聊一聊 jquery?
答: jQuery 是一款轻量级的 js 框架,jQuery 核心 js 文件才几十 kb,不会影响页面加载速度。与 Extjs
相比要轻便的多。 jQuery 的选择器用起来很方便,好比说我要找到某个 dom 对象的相邻元素 js 可能要写好几行代码,而 jQuery
一行代码就搞定了,再比如我要将一个表格的隔行变色,jQuery 也是一行代码搞定。 jQuery 的链式操作可以把多个操作写在一行代码里。
jQuery 还简化了 js 操作 css 的代码,并且代码的可读性也比 js 要强。 jQuery 简化了 AJAX
操作,后台只需返回一个 JSON 格式的字符串就能完成与前台的通信。 jQuery
基本兼容了现在主流的浏览器,不用再为浏览器的兼容问题而伤透脑筋。 jQuery
有着丰富的第三方的插件,例如:树形菜单、日期控件、图片切换插件、弹出窗口等等基本前台页面上的组件都有对应插件,并且用 jQuery
插件做出来的效果很炫,并且可以根据自己需要去改写和封装插件,简单实用。 jQuery 可扩展性强,jQuery
提供了扩展接口:jQuery.extend(object), 可以在 jQuery 的命名空间上增加新函数。jQuery
的所有插件都是基于这个扩展接口开发的。
jquery 对象和 dom 对象怎么转换的?
答: [0] 可以转化为 DOM 对象 $(domObject) 可以转化为 jQuery 对象 jquery 中如何将数组转化为 json
字符串,然后再转化回来? 答:
$.fn.stringifyArray = function(array) {
return JSON.stringify(array)
}
$.fn.parseArray = function(array) {
return JSON.parse(array)
} 然后调用:
( " " ) . s t r i n g i f y A r r a y ( a r r a y ) j Q u e r y 的 源 码 看 过 吗 ? 能 不 能 简 单 概 况 一 下 它 的 实 现 原 理 ? 答 : 1 、 闭 包 机 制 ; / / 以 下 截 取 自 j q u e r y 源 码 片 段 ( f u n c t i o n ( w i n d o w , u n d e f i n e d ) / ∗ 源 码 内 容 ∗ / ) ( w i n d o w ) ; 上 面 这 一 小 段 代 码 来 自 于 1.9.0 当 中 j q u e r y 的 源 码 , 它 是 一 个 无 污 染 的 J S 插 件 的 标 准 写 法 , 专 业 名 词 叫 闭 包 。 可 以 把 它 简 单 的 看 做 是 一 个 函 数 , 与 普 通 函 数 不 同 的 是 , 这 个 函 数 没 有 名 字 , 而 且 会 立 即 执 行 我 们 将 里 面 的 变 量 变 成 了 局 域 变 量 , 这 不 仅 可 以 提 高 运 行 速 度 , 更 重 要 的 是 我 们 在 引 用 j q u e r y 的 J S 文 件 时 , 不 会 因 为 j q u e r y 当 中 的 变 量 太 多 , 而 与 其 它 的 J S 框 架 的 变 量 命 名 产 生 冲 突 ; 闭 包 中 的 变 量 声 明 没 有 污 染 到 外 面 的 全 局 变 量 ; ; 2 、 作 为 全 局 的 一 个 属 性 ; w i n d o w . j Q u e r y = w i n d o w . ("").stringifyArray(array) jQuery 的源码看过吗?能不能简单概况一下它的实现原理? 答: 1、闭包机制; // 以下截取自 jquery 源码片段 (function( window, undefined ) { /* 源码内容 */ })( window ); 上面这一小段代码来自于 1.9.0 当中 jquery 的源码,它是一个无污染的 JS 插件的标准写法,专业名词叫闭包。可以把它简单的看做是一个函数,与普通函数不同的是,这个函数没有名字,而且会立即执行 我们将里面的变量变成了局域变量,这不仅可以提高运行速度,更重要的是我们在引用 jquery 的 JS 文件时,不会因为 jquery 当中的变量太多,而与其它的 JS 框架的变量命名产生冲突;闭包中的变量声明没有污染到外面的全局变量;; 2、作为全局的一个属性; window.jQuery = window. ("").stringifyArray(array)jQuery的源码看过吗?能不能简单概况一下它的实现原理?答:1、闭包机制;//以下截取自jquery源码片段(function(window,undefined)/∗源码内容∗/)(window);上面这一小段代码来自于1.9.0当中jquery的源码,它是一个无污染的JS插件的标准写法,专业名词叫闭包。可以把它简单的看做是一个函数,与普通函数不同的是,这个函数没有名字,而且会立即执行我们将里面的变量变成了局域变量,这不仅可以提高运行速度,更重要的是我们在引用jquery的JS文件时,不会因为jquery当中的变量太多,而与其它的JS框架的变量命名产生冲突;闭包中的变量声明没有污染到外面的全局变量;;2、作为全局的一个属性;window.jQuery=window. = jQuery; 这一句话将我们在闭包当中定义的 jQuery 对象导出为全局变量
jQuery 和 $,因此我们才可以在外部直接使用 jQuery 和 $。 window 是默认的 JS 上下文环境,因此将对象绑定到
window 上面,就相当于变成了传统意义上的全局变量, 3、最核心的功能,就是选择器; 首先我们进入 jquery
源码中,可以很容易的找到 jquery 对象的声明,看过以后会发现,原来我们的 jquery 对象就是 init 对象。
jQuery = function( selector, context ) {
return new jQuery.fn.init( selector, context, rootjQuery );
}
这里出现了 jQuery.fn 这样一个东西,它的由来可以在 jquery 的源码中找到,它其实代表的就是 jQuery 对象的原型。
jQuery.fn = jQuery.prototype;
jQuery.fn.init.prototype = jQuery.fn;
这两句话,第一句把 jQuery 对象的原型赋给了 fn 属性,第二句把 jQuery 对象的原型又赋给了 init 对象的原型。也就是说,init 对象和 jQuery 具有相同的原型,因此我们在上面返回的 init 对象,就与 jQuery 对象有一样的属性和方法。
我们不打算深究 init 这个方法的逻辑以及实现,但是我们需要知道的是,jQuery 其实就是将 DOM 对象加了一层包裹,而寻找某个或者若干个 DOM 对象是由 sizzle 选择器负责的,
jQuery 对象有很多的属性和方法;对于属性来说,我们最需要关注的只有一个属性,就是 [0] 属性,[0] 其实就是原生的 DOM 对象。
很多时候,我们在 jQuery 和 DOM 对象之间切换时需要用到 [0] 这个属性。
从截图也可以看出,jQuery 对象其实主要就是把原生的 DOM 对象存在了 [0] 的位置,并给它加了一系列简便的方法。
这个索引 0 的属性我们可以从一小段代码简单的看一下它的由来,下面是 init 方法中的一小段对 DOMElement 对象作为选择器的源码。
// Handle $(DOMElement)
if ( selector.nodeType ) {
/* 可以看到,这里将 DOM 对象赋给了 jQuery 对象的 [0] 这个位置 */
this.context = this[0] = selector;
this.length = 1;
return this;
}
这一小段代码可以在 jquery 源码中找到,它是处理传入的选择参数是一个 DOM 对象的情况。
可以看到,里面很明显的将 jQuery 对象索引 0 的位置以及 context 属性,都赋予了 DOM 对象
。代码不仅说明了这一点,也同时说明了,我们使用 $(DOMElement) 可以将一个 DOM 对象转换为 jQuery 对象,从而通过转换获得 jQuery 对象的简便方法。
4、ready 方法
$(function(){}) 或者是 ready 方法;
实现类似 jquery 的 ready 方法的效果我们是可以简单做到的,它的实现原理就是,维护一个函数数组,然后不停的判断 DOM 是否加载完毕,倘若加载完毕就触发所有数组中的函数。
遵循着这一思想,LZ 拿出很久之前写的一个小例子,来给各位看一下。
(function( window, undefined ) {
var jQuery = {
isReady:false,// 文档加载是否完成的标识
readyList:[],// 函数序列
//onload 事件实现
ready : function(fn){
// 如果是函数,加入到函数序列
if(fn && typeof fn == 'function' ){
jQuery.readyList.push(fn);
}
// 文档加载完成,执行函数序列。
if(jQuery.isReady){
for(var i = 0;i < jQuery.readyList.length ;i++){
fn = jQuery.readyList[i];
jQuery.callback(fn);
}
return jQuery;
}
},
// 回调
callback : function(fn){
fn.call(document,jQuery);
}
};
// 导出对象
window.$ = window.jQuery = jQuery;
// 判断加载是否完成
var top = false;
try {
top = window.frameElement == null && document.documentElement;
} catch(e) {}
if ( top && top.doScroll ) {
(function doScrollCheck() {
try {
top.doScroll("left");
jQuery.isReady = true;
jQuery.ready();
} catch(e) {
setTimeout( doScrollCheck, 50 );
}
})();
}
}(window));
这段代码是 LZ 从之前的例子摘出来的,它的实现逻辑非常简单,但是可以达到 jQuery 的 ready 方法的效果,
5、extend 方法
简单说两个 extend 方法的常用方式。 1、使用 jQuery.fn.extend 可以扩展 jQuery 对象,使用
jQuery.extend 可以扩展 jQuery,前者类似于给类添加普通方法,后者类似于给类添加静态方法。 2、两个 extend
方法如果有两个 object 类型的参数,则会将后面的参数对象属性扩展到第一个参数对象上面,扩展时可以再添加一个 boolean
参数控制是否深度拷贝。 jquery find,children,filter 的区别? 答: filter 是对自身集合元素的操作,
children 是对子元素的检索, find 是对它的后代元素的检索操作 .children(selector)
方法是返回匹配元素集合中每个元素的所有子元素(仅儿子辈)。参数可选,添加参数表示通过选择器进行过滤,对元素进行筛选。
.find(selector) 方法是返回匹配元素集合中每个元素的后代。参数是必选的,可以为选择器、jquery
对象可元素来对元素进行筛选。 .find() 与 .children() 方法类似,不同的是后者仅沿着 DOM 树向下遍历单一层级。这里的
children,我理解为儿子,只在儿子这一级遍历。
jQuery 的队列是如何实现的?队列可以用在哪些地方?
答:
jQuery 核心中,有一组队列控制方法,这组方法由 queue()/dequeue()/clearQueue()
三个方法组成,它对需要连续按序执行的函数的控制可以说是简明自如,主要应用于 animate () 方法,ajax
以及其他要按时间顺序执行的事件中。 先解释一下这组方法各自的含义。 queue(name,[callback]):
当只传入一个参数时,它返回并指向第一个匹配元素的队列(将是一个函数数组,队列名默认是 fx); 当有两个参数传入时,第一个参数还是默认为
fx
的的队列名,第二个参数又分两种情况,当第二个参数是一个函数时,它将在匹配的元素的队列最后添加一个函数。当第二个参数是一个函数数组时,它将匹配元素的队列用新的一个队列来代替(函数数组).
可能,这个理解起来有点晕。 dequeue(name): 这个好理解,就是从队列最前端移除一个队列函数,并执行它。
clearQueue([queueName]): 这是 1.4 新增的方法。清空对象上尚未执行的所有队列。参数可选,默认为 fx.
但个人觉得这个方法没多大用,用 queue() 方法传入两个参数的第二种参数即可实现 clearQueue 方法。
现在,我们要实现这样一个效果,有标有 1 至 7 的数字方块,要求这七个方块自左到右依次下落;写好以后
;如果此时,你想调换一个某个的执行顺序,比如,你想让 5 落下后再开始下落 3, 或者新加 8 至 15 八个方块,怎么办?
重写吗?在里面小心冀冀的改吗?显然,我们需要另外一种列简明便捷的方法来实现这个效果,那就是 jQuery 队列控制方法。;
这样一来,看起来是不是简明多了。如何实现? 新建一个数组,把动画函数依次放进去(这样更改顺序,新加动画是不是方便多了?); 用 queue
将这组动画函数数组加入到 slideList 队列中; 用 dequeue 取出 slideList 队列中第一个函数,并执行它;
初始执行第一个函数。 至于 clearQueue() 方法,就不多说了,演示中停止按钮调用的就是 clearQueue()
方法,当然你还可以用 queue() 方法直接将现在的函数列队替换成 [] 空数组实现(个人比较推荐空数组替换。, 更直观).
jQuery 与 jQuery UI 有啥区别?
答: jQuery 是一个 js 库,主要提供的功能是选择器,属性修改和事件绑定等等。 jQuery UI 则是在 jQuery
的基础上,利用 jQuery 的扩展性,设计的插件。 提供了一些常用的界面元素,诸如对话框、拖动行为、改变大小行为等等
jQuery 和 Zepto 的区别?各自的使用场景?
答:zepto 主要用在移动设备上,只支持较新的浏览器,好处是代码量比较小,性能也较好。 jquery 主要是兼容性好,可以跑在各种
pc,移动上,好处是兼容各种浏览器,缺点是代码量大,同时考虑兼容,性能也不够好。 jq 自身也注意到了这个总是,所有它的 2.x
版本是不支持 ie6 7 8 的
针对 jQuery 性能的优化方法?
答:
基于 Class 的选择性的性能相对于 Id 选择器开销很大,因为需遍历所有 DOM 元素。
频繁操作的 DOM,先缓存起来再操作。用 jQuery 的链式调用更好。
比如:var str=$("a").attr("href");
for 循环
for (var i = size; i < arr.length; i++) {
}
for 循环每一次循环都查找了数组 (arr) 的 length 属性,在开始循环的时候设置一个变量来存储这个数字,可以让循环跑得更快:
for (var i = size, length = arr.length; i < length; i++) {
}
jQuery 一个对象可以同时绑定多个事件,这是如何实现的?
答:
$ele.on('eventName', handle1);
$ele.on('eventName', handle2);
$ele.on('eventName', handle3);
其实 $ele 元素的 eventName 事件有一个处理函数数组 监听一次就往里面放一个 handle,数组是先进后出型的
也就是栈, 然后触发事件的时候一次执行
上面的监听相当于
$ele.eventHandle['eventName'] = [];
$ele.eventHandle['eventName'].push(handle1);
$ele.eventHandle['eventName'].push(handle2);
$ele.eventHandle['eventName'].push(handle3);
然后 $ele.trigger('eventName') 触发的时候, 从栈里面取出处理函数执行
while($ele.eventHandle['eventName'].length) {
handle = $ele.eventHandle['eventName'].pop();
handle();
}