0

0

从jQuery中应该明白哪些知识?

零下一度

零下一度

发布时间:2017-06-17 15:41:11

|

1392人浏览过

|

来源于php中文网

原创

最近想看一下jquery源码,搜到了这样一篇博客《从jquery源码学到的10件事情》

本文基于这篇视频博客,提炼了一些内容,分享给大家。

说明:
这篇文章写于2010年,作者在视频里使用的是jQuery 1.4版本,我根据视频里讲到的内容,对应目前的1字头1.11版本做了一些调整,一些被抛弃或者被移除的内容页做了删减,并在此感谢原作者

黑箱/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)
})()

jQuery 1.11版本的黑箱采用了全新的工厂方法,本文不探究

noConflict的实现

这个函数的差异不大,1.11 版本代码如下

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

Avatar AI
Avatar AI

AI成像模型,可以从你的照片中生成逼真的4K头像

下载

特效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                            // http://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里面

相关专题

更多
Word 字间距调整方法汇总
Word 字间距调整方法汇总

本专题整合了Word字间距调整方法,阅读下面的文章了解更详细操作。

2

2025.12.24

任务管理器教程
任务管理器教程

本专题整合了任务管理器相关教程,阅读下面的文章了解更多详细操作。

2

2025.12.24

AppleID格式
AppleID格式

本专题整合了AppleID相关内容,阅读专题下面的文章了解更多详细教程。

0

2025.12.24

csgo视频观看入口合集
csgo视频观看入口合集

本专题整合了csgo观看入口合集,阅读下面的文章了知道更多入口地址。

29

2025.12.24

yandex外贸入口合集
yandex外贸入口合集

本专题汇总了yandex外贸入口地址,阅读下面的文章了解更多内容。

58

2025.12.24

添加脚注通用方法
添加脚注通用方法

本专题整合了添加脚注方法合集,阅读专题下面的文章了解更多内容。

1

2025.12.24

重启电脑教程汇总
重启电脑教程汇总

本专题整合了重启电脑操作教程,阅读下面的文章了解更多详细教程。

3

2025.12.24

纸张尺寸汇总
纸张尺寸汇总

本专题整合了纸张尺寸相关内容,阅读专题下面的文章了解更多内容。

5

2025.12.24

Java Spring Boot 微服务实战
Java Spring Boot 微服务实战

本专题深入讲解 Java Spring Boot 在微服务架构中的应用,内容涵盖服务注册与发现、REST API开发、配置中心、负载均衡、熔断与限流、日志与监控。通过实际项目案例(如电商订单系统),帮助开发者掌握 从单体应用迁移到高可用微服务系统的完整流程与实战能力。

1

2025.12.24

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
jQuery 教程
jQuery 教程

共42课时 | 3.3万人学习

HTML+CSS基础与实战
HTML+CSS基础与实战

共132课时 | 9.2万人学习

tp6+adminlte搭建通用后台
tp6+adminlte搭建通用后台

共39课时 | 5.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号