沉沙
2018-07-18
来源 :
阅读 1856
评论 0
摘要:本篇jQuery教程探讨了小白学习jQuery应该掌握的几件事情,希望阅读本篇文章以后大家有所收获,帮助大家对jQuery的理解更加深入。
黑箱/Black box
黑箱系统的概念是给定输入返回输出的一个系统,黑箱把实现过程进行封装。这里说的jQuery黑箱是为js全局变量window输出jQuery 和 $,而过程被封装到黑箱里,与外界互不干扰。
jQuery 1.4版本的黑箱是利用了类似如下的自执行函数
(function( window, undefined){})(window)
undefined = true;
(function(window, document, undefined){
if(foo == undefined) {
}
})(this, document)jQuery的黑箱里多传了第三个形参叫做undefined,而传实参的时候并没有传值,js里没有传值的形参会被设置为undefined,保证了黑箱内部undefined的正确性。js中,undefined作为一个全局属性,是可以被赋值的,比如上述代码中的undefined = true;
以自执行函数的模式实现黑箱的另外一个好处是利于压缩,比如下述的情况,我们只需要在黑箱内部使用简单的变量。
(function(A, B, C)){
B.getElementById('')
})(this, document)
匿名函数自执行例子比如下面这个,为页面的某一部分不停地更新(以及不断地执行)
(function loop(){
doStuff();
$('#update').load('awesomething.php',function(){
loop();
})
//setTimeout(loop, 100)
})()
noConflict的实现
这个函数的差异不大
var
// Map over jQuery in case of overwrite
_jQuery = window.jQuery,
// Map over the $ in case of overwrite
_$ = window.$;
jQuery.noConflict = function( deep ) {
if ( window.$ === jQuery ) {
window.$ = _$;
}
if ( deep && window.jQuery === jQuery ) {
window.jQuery = _jQuery;
}
return jQuery;
};我们可以看到防冲突的实现是先把之前的JQuery 和 $ 存起来,noConflict被调用的时候,再还给它们
与原生js属性命名的转换
1.4版本用的是props对象来存放jquery对属性操作与原生js属性操作的对应关系
1.11版缩减版本是这样的
jQuery.extend({
propFix: {
"for": "htmlFor",
"class": "className"
},
prop: function( elem, name, value ) {
//...
name = jQuery.propFix[ name ] || name;
},
propHooks: {
//...
}
});
jQuery.each([
"tabIndex",
"readOnly",
"maxLength",
"cellSpacing",
"cellPadding",
"rowSpan",
"colSpan",
"useMap",
"frameBorder",
"contentEditable"
], function() {
jQuery.propFix[ this.toLowerCase() ] = this;
});propFix 这个对象是存放对应关系表的,比如class转换成className,prop函数负责处理这个关系表。
而下面的each很有意思,遍历数组中那些属性,然后把他们小写格式对应到自己,放到 propFix
特效Speed
我们知道在jQuery里一些动画我们可以直接通过normal,fast,slow 来定义实现速度,这个在源码里是这样定义的
jQuery.fx.speeds = { slow: 600, fast: 200,
// Default speed _default: 400
};
var isIE //...
jQuery.fx.speeds._default = isIE ? 800 : 400
jQuery.fx.speeds.veryfast = 200;
$('...').fadeIn('veryfast')一种是可以对default属性做条件判断,还有一种自定义速度,比如"veryfast"
.ready
ready函数 1.11版本和1.4版本有较大的差距,我们就简单的把核心拿出来看一下
jQuery.ready.promise = function( obj ) {
//...省略若干
} else if ( document.addEventListener ) {
// 使用addEventListener "DOMContentLoaded" 监听ready事件
document.addEventListener( "DOMContentLoaded", completed, false );
// 备选方案 "load"
window.addEventListener( "load", completed, false );
//如果IE
} else {
// Ensure firing before onload, maybe late but safe also for iframes
//IE下 attachEvent 的"onreadystatechange"
document.attachEvent( "onreadystatechange", completed );
// A fallback to window.onload, that will always work
//备选方案onload
window.attachEvent( "onload", completed );
// If IE and not a frame
// continually check to see if the document is ready
var top = false;
try {
top = window.frameElement == null && document.documentElement;
} catch(e) {}
if ( top && top.doScroll ) {
(function doScrollCheck() {
if ( !jQuery.isReady ) {
try {
// Use the trick by Diego Perini
// //javascript.nwbox.com/IEContentLoaded/
top.doScroll("left");
} catch(e) {
return setTimeout( doScrollCheck, 50 );
}
// detach all dom ready events
detach();
// and execute any waiting functions
jQuery.ready();
}
})();
}
}
}
return readyList.promise( obj );
};.ready 利用了下面的.promise去做确保载入完成的工作,重点是
document.addEventListener( "DOMContentLoaded", completed, false );
window.addEventListener( "load", completed, false );
document.attachEvent( "onreadystatechange", completed );
window.attachEvent( "onload", completed );
兼容性考量的四种检查方式
其中从top开始,做了一件事情就是IE下面,dom节点判断是否有scroll,在IE下如果dom有scroll,没有scroll到的元素对ready会有影响,总之jQuery里用到了一个叫做Diego Perini的技巧,可以在注释里的地址看到更多内容。
选择器
$('#id').find('tag.thing') --- faster
$('#id tag.thing') ------- using sizzle
原作者在这里说了一个jquery效率的问题,上面的方法更快一些,而下面的方法稍微慢,简单地说是因为下面的方法调用了sizzle,通过sizzle其实转换成上述的模式,而id的调用则是直接过jQuery.init.
这里需要扩展一下,我们来看一下1.11里jQuery对象究竟长啥样
jQuery = function( selector, context ) {
// The jQuery object is actually just the init constructor 'enhanced'
// Need init if jQuery is called (just allow error to be thrown if not included)
return new jQuery.fn.init( selector, context );
}
jQuery对象其实是return了一个它自己的构造函数叫做init,我们再来看一下init做了些什么
// Initialize a jQuery object
init = jQuery.fn.init = function( selector, context ) {
var match, elem;
// HANDLE: $(""), $(null), $(undefined), $(false)
//超级省略...下略
// Handle HTML strings
// HANDLE: $(html) -> $(array)
// HANDLE: $(html, props)
// HANDLE: $(#id)
// HANDLE: $(expr, $(...))
// HANDLE: $(expr, context)
// HANDLE: $(DOMElement)
// HANDLE: $(function)
return jQuery.makeArray( selector, this );
};
// Give the init function the jQuery prototype for later instantiation
init.prototype = jQuery.fn;
从上面的摘取的代码注释中,我们可以看到jq自己的构造函数里处理了哪些情况,其中包括html标签名和id的获取,意味着这两种获取是最底层的,此外$()的其他处理都要经过其他的函数,效率上不如上述处理情况。
同时我们也能看到init的原型被赋予了jQuery.fn, 关于jQuery对象的相关内容,感兴趣的朋友可以再多去了解一些。
jQ的状态选择符,比如:not,:has,:eq存放在
Sizzle.selectors.pseudos里面
本文由职坐标整理发布,欢迎关注职坐标WEB前端jQuery频道,获取更多jQuery知识!
喜欢 | 0
不喜欢 | 0
您输入的评论内容中包含违禁敏感词
我知道了

请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号