- 浏览: 521055 次
- 性别:
- 来自: 北京
博客专栏
-
jQuery技术内幕
浏览量:200742
最新评论
-
青春依旧:
学习html5哪里好?当然华清远见是首选!
[原创] jQuery源码分析-01总体架构 -
追梦1819:
[size=x-small][color=red][/colo ...
[原创] jQuery源码分析-04 选择器-Sizzle-设计思路 -
niuqiang2008:
学习学习
[原创] jQuery源码分析-04 选择器-Sizzle-工作原理 -
liuweihug:
jquery 解析正则表达式及常见的Regex规则和表达式 - ...
[原创] jQuery源码分析-02正则表达式-RegExp-常用正则表达式 -
liang8768:
mark!!!
[原创] jQuery源码分析-00前言开光
作者:nuysoft/JS攻城师/高云 QQ:47214707 EMail:nuysoft@gmail.com 声明:本文为原创文章,如需转载,请注明来源并保留原文链接。 后文预告:封装事件对象 便捷接口解析 前记: 这一章写的很用心,希望有所启发。因为排版的原因,阅读附件PDF更方便一些。 jQuery源码分析系列大概已经写了60%,架构、构建jQuery对象、异步队列、浏览器测试、数据缓存、队列、事件模型、AJAX、动画、尺寸大小基本完结,这些比较难读也是我感兴趣的,剩余的部分有选择器、DOM遍历和操作、CSS和部分章节的补充,jQuery中的正则分析已有初稿但是内容太庞大还在拿捏怎么写合适,一些章节写的不是很满意有时间会做修改,详细的目录和计划可以去目录页参看 http://nuysoft.iteye.com/blog/1190542。 JavaScript同其他语言一样,基础非常重要,仅仅会用框架和工具写一些WebApp是不能成为一名合格的JS工程师的,建议多读几次JavaScript权威指南,以我的经验与Java相比,JavaScript需要花费与Java相当的时间才能达到与Java相当的水平。 jQuery完结之后计划写Java开源框架的源码解析,从Spring、Hibernate开始,有兴趣的同学可以一起研究。
10.8 DOM ready 初学jQuery时,很可能学到的第一个知识点就是.ready(),但是网络上流转的文章和API对此的解释或剖析,经常是模棱两可甚至是不准确或错误的,本节将详细的阐述.ready()的用法和原理,并纠正这些误区。 10.8.1 如何使用.ready() .ready() 指定一个事件句柄,当DOM完全加载完成时执行 虽然JavaScript提供了load事件,当页面渲染完成之后会执行这个函数,在所以元素加载完成之前,这个函数不会被调用,例如图像。但是在大多数情况下,只要DOM结构加载完,脚本就可以尽快运行。传递给.ready()的事件句柄在DOM准备好后立即执行,因此通常情况下,最好把绑定事件句柄和其他jQuery代码都到这里来。但是当脚本依赖于CSS样式属性时,一定要在脚本之前引入外部样式或内嵌样式的元素。 如果代码依赖于需加载完的元素(例如,想获取一个图片的尺寸大小),应该用.load()事件代替,并把代码放到load事件句柄中。 .ready()方法不同于<body onload="">属性。如果必须用load事件,那么就不要使用.ready(),或用.load()代替,把load事件句柄绑定到window或其他的具体元素上,例如图片。 以下三个语法全部是等价的: $(document).ready(handler) $().ready(handler) (this is not recommended) $(handler) $(document).bind("ready", handler)的行为类似于ready方法,但有一个例外:如果ready事件已触发后,再尝试用.bind("ready")绑定的处理函数将不会被执行。而用以上三种方法绑定的句柄会被执行,无论是什么时候绑定的。 .ready()方法只能在包含了document的jQuery上调用,因此选择器可以省略。 .ready()方法典型的用法是使用一个匿名函数: $(document).ready(function() { // Handler for .ready() called. }); 等价于: $(function() { // Handler for .ready() called. }); 如果在DOM加载完毕之后调用.ready(),新的句柄将会立即执行。 特别强调两点: 1. 之所以花费篇幅来阐述.ready()如何使用(翻译的官网文档),是因为网络上的一些文章和中文API不准确甚至是错误的(应该是工具翻译的),所以需谨慎参考 2. .ready()的触发要早于.load(),但是不要完全迷信依赖,如果要获取或操作样式,或依赖于像图片这样的必须加载完成才能获取和操作的元素,就用<body onload="">或.load() 10.8.2 源码分析 到底.ready()是如何实现更快的触发ready事件的呢,关键在jQuery.bindReady方法的实现里: 对标准浏览器绑定:document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); 对IE浏览器绑定:document.attachEvent( "onreadystatechange", DOMContentLoaded ); 当然还有一些其他的关键技巧,现在完成的看下jQuery.bindReady的实现: // 绑定DOM ready监听器,跨浏览器,兼容标准浏览器和IE浏览器 bindReady: function() { // jQuery.bindReady if ( readyList ) { return; } readyList = jQuery._Deferred(); // 初始化ready异步事件句柄队列 // Catch cases where $(document).ready() is called after the // browser event has already occurred. // 如果DOM已经完毕,立即调用jQuery.ready if ( document.readyState === "complete" ) { // Handle it asynchronously to allow scripts the opportunity to delay ready // 重要的是异步 return setTimeout( jQuery.ready, 1 ); } // Mozilla, Opera and webkit nightlies currently support this event // DOM 2级事件模型,Mozilla, Opera, webkit等 if ( document.addEventListener ) { // Use the handy event callback // 使用快速事件句柄 document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); // A fallback to window.onload, that will always work // 再在window上绑定load事件句柄,这个句柄总是会执行 // 为什么同时绑定document window呢?我想是为了安全起见,防御性编码! window.addEventListener( "load", jQuery.ready, false ); // If IE event model is used } else if ( document.attachEvent ) { // ensure firing before onload, // maybe late but safe also for iframes // 同样onreadystatechange会在onload之前触发,但是对于iframe会有延迟但安全一定会触发 // 看看DOMContentLoaded的实现,是检测document.readyState的状态是否为complete,这里有些像ajax中的检测 document.attachEvent( "onreadystatechange", DOMContentLoaded ); // A fallback to window.onload, that will always work window.attachEvent( "onload", jQuery.ready ); // 同样的安全起见,防御性编码!及时前边的所以hack技巧失败了,onload是最后的保障 // If IE and not a frame // continually check to see if the document is ready var toplevel = false; try { toplevel = window.frameElement == null; // 检查window的frameElement属性,看是否是顶层窗口 } catch(e) {} // 做doScroll检测,如果在iframe中就不检测了,onreadystatechange对于ifame很可靠 if ( document.documentElement.doScroll && toplevel ) { doScrollCheck(); // 在doScrollCheck中,不断的(每隔1ms)执行document.documentElement.doScroll("left"),直到不抛出异常为止 // 这是IE下检测DOM ready的技巧 } } }, 然后是完整的ready相关方法的分析,我剔除了其他无关的代码,保留了整体结构和相关方法: (function( window, undefined ) { var jQuery = (function() { // Define a local copy of jQuery var jQuery = function( selector, context ) { // The jQuery object is actually just the init constructor 'enhanced' var ret = new jQuery.fn.init( selector, context, rootjQuery ); return ret; }, // A central reference to the root jQuery(document) rootjQuery, // 包含了document的jQuery对象 // The deferred used on DOM ready readyList, // ready事件处理函数队列 // The ready event handler DOMContentLoaded, // DOM ready hack句柄,.ready()能早于.load()的关键所在 jQuery.fn = jQuery.prototype = { constructor: jQuery, init: function( selector, context, rootjQuery ) { // HANDLE: $(function) // Shortcut for document ready // 如果函数,则认为是DOM ready句柄 if ( jQuery.isFunction( selector ) ) { return rootjQuery.ready( selector ); } }, ready: function( fn ) { // Attach the listeners jQuery.bindReady(); // 绑定DOM ready监听器,跨浏览器,兼容标准浏览器和IE浏览器 // Add the callback readyList.done( fn ); // 将ready句柄添加到ready异步句柄队列 return this; } }; // Give the init function the jQuery prototype for later instantiation jQuery.fn.init.prototype = jQuery.fn; jQuery.extend = jQuery.fn.extend = function() {}; jQuery.extend({ // Is the DOM ready to be used? Set to true once it occurs. // DOM是否加载完毕 isReady: false, // A counter to track how many items to wait for before // the ready event fires. See #6781 // DOM加载完毕之前的等待次数 readyWait: 1, // Hold (or release) the ready event // 是否延迟触发DOM ready?在jQuery中没有任何地方有调用到holdReady,这是个遗留方法还是预留方法,有待继续研究。 // 因此在当前版本中,readyWait总是1,直到自减 holdReady: function( hold ) { if ( hold ) { // 继续等待 jQuery.readyWait++; } else { jQuery.ready( true ); // } }, // Handle when the DOM is ready // 判断DOM是否加载完毕,如果已完毕,调用DOM ready事件异步队列readyList,如果未完,每个1ms检查一次 ready: function( wait ) { // jQuery.ready // Either a released hold or an DOMready/load event and not yet ready // 条件1:wait === true && !--jQuery.readyWait 还在等待加载完成,但是等待计数器jQuery.readyWait已经是0, // 换句话说参数wait为true表示尝试一下看是否能开始调用readyList了,如果发现计数器jQuery.readyWait变成0,啥也不管了,开始调用吧 // 再换句话说,计数器已经是0了,开干吧 // 条件2:wait !== true && !jQuery.isReady 明确的说不用了,即使DOM ready标记还是false // 换句话说,及时DOM ready标记还是false,但是调用jQuery.ready的客户端认为不比再等了,可以开干了 if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) { // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). // 检查document.body是否存在,这是特定于IE的检测,保证在IE中DOM ready事件能正确判断 if ( !document.body ) { return setTimeout( jQuery.ready, 1 ); } // Remember that the DOM is ready // 到这里,jQuery.isReady被强制为true // 在条件2中,如果jQuery.isReady为true,那么说明readyList的状态已经确定,添加到readyList中的函数会被立即执行 // 如果jQuery.isReady为是false,那么接下来readyList中函数将被执行 jQuery.isReady = true; // If a normal DOM Ready event fired, decrement, and wait if need be // 虽然上边的条件2的意思是,别管其他情况,调用方认为ready了,但是这里仍然做了防御性检测,如果等待计数器仍然大于1,结束ready调用 // 如果这个条件成立,那么一定是哪里出问题了! // 在当前版本1.6.1中,这个判断永远不会成立,因为没有地方调用会使readyWait加一的holdReady if ( wait !== true && --jQuery.readyWait > 0 ) { return; } // If there are functions bound, to execute // 调用DOM ready事件异步队列readyList,注意整理的参数亮了! // document指定了ready句柄的上下文,这样我们在执行ready事件句柄时this指向document // [ jQuery ]指定了ready事件句柄的第一个参数,这样即使调用$.noConflict()交出了$的控制权,我们依然可以将句柄的第一个参数命名为$,继续在句柄内部使用$符号 // 如此的精致!赞叹之余,但不要在你的项目中也这么用,理解和维护将成为最大的难题。 readyList.resolveWith( document, [ jQuery ] ); // Trigger any bound ready events if ( jQuery.fn.trigger ) { // 触发ready事件,然后删除ready句柄,DOM ready事件只会生效一次,ready是个自定义事件 jQuery( document ).trigger( "ready" ).unbind( "ready" ); } } }, // 绑定DOM ready监听器,跨浏览器,兼容标准浏览器和IE浏览器 bindReady: function() { // jQuery.bindReady if ( readyList ) { return; } readyList = jQuery._Deferred(); // 初始化ready异步事件句柄队列 // Catch cases where $(document).ready() is called after the // browser event has already occurred. // 如果DOM已经完毕,立即调用jQuery.ready if ( document.readyState === "complete" ) { // Handle it asynchronously to allow scripts the opportunity to delay ready // 重要的是异步 return setTimeout( jQuery.ready, 1 ); } // Mozilla, Opera and webkit nightlies currently support this event // DOM 2级事件模型,Mozilla, Opera, webkit等 if ( document.addEventListener ) { // Use the handy event callback // 使用快速事件句柄 document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); // A fallback to window.onload, that will always work // 再在window上绑定load事件句柄,这个句柄总是会执行 // 为什么同时绑定document window呢?我想是为了安全起见,防御性编码! window.addEventListener( "load", jQuery.ready, false ); // If IE event model is used } else if ( document.attachEvent ) { // ensure firing before onload, // maybe late but safe also for iframes // 同样onreadystatechange会在onload之前触发,但是对于iframe会有延迟但安全一定会触发 // 看看DOMContentLoaded的实现,是检测document.readyState的状态是否为complete,这里有些像ajax中的检测 document.attachEvent( "onreadystatechange", DOMContentLoaded ); // A fallback to window.onload, that will always work window.attachEvent( "onload", jQuery.ready ); // 同样的安全起见,防御性编码!及时前边的所以hack技巧失败了,onload是最后的保障 // If IE and not a frame // continually check to see if the document is ready var toplevel = false; try { toplevel = window.frameElement == null; // 检查window的frameElement属性,看是否是顶层窗口 } catch(e) {} // 做doScroll检测,如果在iframe中就不检测了,onreadystatechange对于ifame很可靠 if ( document.documentElement.doScroll && toplevel ) { doScrollCheck(); // 在doScrollCheck中,不断的(每隔1ms)执行document.documentElement.doScroll("left"),直到不抛出异常为止 // 这是IE下检测DOM ready的技巧 } } }, }); // All jQuery objects should point back to these rootjQuery = jQuery(document); // Cleanup functions for the document ready method // 构造浏览器加载完毕事件处理函数DOMContentLoaded,需要检测浏览器添加事件的方法 if ( document.addEventListener ) { DOMContentLoaded = function() { // document ready之后移除 document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); jQuery.ready(); }; } else if ( document.attachEvent ) { DOMContentLoaded = function() { // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). // 确保body是存在的,IE会有一些延迟 if ( document.readyState === "complete" ) { // 先移除,难道浏览器重新渲染会再次触发onreadystatechange吗? document.detachEvent( "onreadystatechange", DOMContentLoaded ); jQuery.ready(); } }; } // The DOM ready check for Internet Explorer // 在IE里,每隔1ms检测IE浏览器的ready状态 function doScrollCheck() { if ( jQuery.isReady ) { return; } try { // If IE is used, use the trick by Diego Perini // http://javascript.nwbox.com/IEContentLoaded/ // 如果是IE,则使用该技巧来检测浏览器加载状态 document.documentElement.doScroll("left"); } catch(e) { setTimeout( doScrollCheck, 1 ); return; } // and execute any waiting functions // 执行其他的等待函数 jQuery.ready(); } // Expose jQuery to the global object return jQuery; })(); // 见系列文章中关于异步队列的解析 jQuery.extend({ // Create a simple deferred (one callbacks list) _Deferred: function() {}, // Full fledged deferred (two callbacks list) Deferred: function( func ) {}, // Deferred helper when: function( firstParam ) {} }); // 见系列文章中关于事件的解析 jQuery.event = { trigger: function( event, data, elem, onlyHandlers ) {}, handle: function( event ) {}, special: { ready: { // Make sure the ready event is setup setup: jQuery.bindReady, teardown: jQuery.noop } } }; window.jQuery = window.$ = jQuery; })(window);
- _原创__jQuery源码分析-10事件处理-Event-DOM-ready.pdf (367.3 KB)
- 下载次数: 164
评论
4 楼
nuysoft
2011-12-03
filod 写道
holdReady是早已公开的函数,估计在编写插件的时候较常使用。既非遗留方法也非预留方法。
不知道为什么LZ这么喜欢“句柄”一词,个人觉得不太好,容易使人误解。
不过依然非常感谢LZ的工作!
不知道为什么LZ这么喜欢“句柄”一词,个人觉得不太好,容易使人误解。
不过依然非常感谢LZ的工作!
谢谢提示,确实holdReady是公开的函数http://api.jquery.com/jQuery.holdReady/
3 楼
filod
2011-12-03
holdReady是早已公开的函数,估计在编写插件的时候较常使用。既非遗留方法也非预留方法。
不知道为什么LZ这么喜欢“句柄”一词,个人觉得不太好,容易使人误解。
不过依然非常感谢LZ的工作!
不知道为什么LZ这么喜欢“句柄”一词,个人觉得不太好,容易使人误解。
不过依然非常感谢LZ的工作!
2 楼
nuysoft
2011-11-24
晨曦的朝阳 写道
经过LZ这么一分析,原来也是可以大概看懂的,致敬!
事件模块的代码相对简单些,不懂的地方反复看几遍就了然了
1 楼
晨曦的朝阳
2011-11-21
经过LZ这么一分析,原来也是可以大概看懂的,致敬!
发表评论
-
[原创] jQuery源码分析-04 选择器-Sizzle-设计思路
2011-11-14 20:59 6850作者:nuysoft/高云 QQ:47214707 Em ... -
[原创] jQuery源码分析-04 选择器-Sizzle-工作原理
2011-11-13 23:45 7886作者:nuysoft/高云 QQ:47214707 EM ... -
[原创] jQuery源码分析-02正则表达式-RegExp-常用正则表达式
2011-10-27 01:29 46638作者:nuysoft/JS攻城师/ ... -
[原创] jQuery源码分析-jQuery中的循环技巧
2011-10-27 00:36 14546作者:nuysoft/JS攻城师/高云 QQ:47214707 ... -
[原创] jQuery源码分析-Java工程师应该向jQuery学习的8点建议
2011-10-18 23:56 12247作者:nuysoft/高云 QQ:47214707 EM ... -
[原创] jQuery源码分析-10事件处理-Event-事件绑定与删除-bind/unbind+live/die+delegat/undelegate
2011-10-18 22:31 15666作者:nuysoft/高云 QQ:47214707 EM ... -
[原创] jQuery源码分析-10事件处理-Event-源码结构
2011-10-17 01:01 12118作者:nuysoft/高云 QQ:47214707 EMail ... -
[原创] jQuery源码分析-07数据缓存-Cache
2011-10-13 19:55 12131作者:nuysoft/高云 QQ:47214707 EMail ... -
[原创] jQuery源码分析-06浏览器测试-Support
2011-10-13 19:19 9904作者:nuysoft/高云 QQ:47214707 EMail ... -
[原创] jQuery源码分析系列目录(持续更新)
2011-10-12 12:30 29358作者:nuysoft/高云 QQ:47214707 E ... -
[原创] jQuery源码分析-10事件处理-Event-概述和基础知识
2011-10-12 00:16 12008作者:nuysoft/高云 Q ... -
[原创] jQuery源码分析-08队列 Queue
2011-10-10 23:48 10790作者:nuysoft/高云 Q ... -
[原创] jQuery源码分析-03构造jQuery对象-工具函数
2011-09-29 23:21 29780作者:nuysoft/高云 QQ:47214707 E ... -
[原创] jQuery源码分析-15AJAX-类型转换器
2011-09-29 02:25 7407作者:nuysoft/高云 QQ:47214707 EM ... -
[原创] jQuery源码分析-03构造jQuery对象-源码结构和核心函数
2011-09-28 02:20 52963作者:nuysoft/高云 QQ:47214707 EMail ... -
[原创] jQuery源码分析-如何做jQuery源码分析
2011-09-27 00:22 15000近期在ITEYE陆续写了几篇jQuery源码分析,乐在其 ... -
[原创] jQuery源码分析-17尺寸和大小 Dimensions & Offset
2011-09-25 22:05 7049边读边写,不正确的地方,还请各位告诉我,多多交流共同学习, ... -
[原创] jQuery源码分析-15AJAX-前置过滤器和请求分发器
2011-09-23 00:09 13281边读边写,不正确的 ... -
[原创] jQuery源码分析-00前言开光
2011-09-21 23:42 47001jQuery源码分析 - 前言 jQuery凭借简洁的语法和 ... -
[原创] jQuery源码分析-01总体架构
2011-09-21 23:31 751331. 总体架构 1.1 自调用匿名函 ...
相关推荐
《jQuery源码分析——魔术方法》 jQuery,作为一款广泛使用的JavaScript库,以其简洁的API和强大的功能赢得了开发者们的喜爱。在深入理解jQuery的工作原理时,我们常常会遇到一些“魔术方法”,这些方法在特定场景...
jQuery是一个轻量级的JavaScript库,它极大地简化了JavaScript的DOM操作、事件处理、动画设计和Ajax交互。它的API设计易于理解和使用,使得开发者能够用更少的代码实现更多的功能,提高了开发效率。 2. **jQuery ...
jQuery,作为一款广泛使用的JavaScript库,极大地简化了DOM操作、事件处理、动画设计以及Ajax交互。本文将围绕标题中的"jQuery-2.2.4.js"进行深入探讨,旨在帮助开发者更好地理解和应用这一版本的jQuery。 首先,...
2. 事件监听:jQuery-simple-tree提供了丰富的事件接口,如`nodeClick`、`nodeCollapse`、`nodeExpand`等,便于对用户操作进行响应。 ```javascript $('#treeElement').on('nodeClick', function(event, node) { ...
jQuery提供了统一的事件处理方式,如`$(selector).click(function)`用于绑定点击事件,`$(selector).hover(functionIn, functionOut)`用于处理鼠标悬停事件,`$(document).ready(function)`用于在页面加载完成后执行...
4. **事件处理**:事件绑定功能得到了加强,$.event特殊事件和$.proxy()函数的引入,使得事件处理更加灵活,可以更好地处理冒泡和委托事件。 5. **动画效果**:jQuery 1.2增强了动画效果的控制,如animate()方法...
在分析jQuery源码时,事件处理是不可绕过的一个重要领域。由于不同浏览器间事件对象的差异,jQuery需要提供一个统一的事件处理机制以保证代码的兼容性和一致性。本知识点将深入探讨jQuery源码中Event模块的设计和...
jQuery,作为一个轻量级的JavaScript库,简化了DOM操作、事件处理以及Ajax交互,极大地提高了前端开发效率。而Django,则是Python的一个高级Web框架,以其MVT(Model-View-Template)架构模式著称,提供了强大的后端...
**jQuery 是一个广泛使用的 JavaScript 库,它极大地简化了 JavaScript 的 DOM 操作、事件处理、动画设计以及Ajax交互。在本篇文章中,我们将深入探讨 jQuery 的核心特性、优点以及如何在实际项目中应用这两个文件:...
使用`$(element).on("event", function)`可以绑定事件监听器,如`$(document).ready(function)`确保在文档加载完成后执行特定代码。此外,`$(element).click(function)`、`$(element).hover(functionIn, functionOut...
2. jQuery插件:`z-pager.js`是基于jQuery库的插件,利用jQuery强大的DOM操作能力和事件处理能力,简化了分页功能的实现。 二、插件引入 要使用`z-pager.js`分页插件,首先需要在HTML文档中引入以下两个文件: 1....
3. **事件处理**:jQuery的事件处理机制非常灵活,`$('selector').on('event', handler)`用于绑定事件,`$('selector').off('event')`取消绑定。同时,`$(document).ready(function() {...})`或`$(function() {...})...
jQuery 是一个广泛使用的 JavaScript 库,它极大地简化了网页的DOM操作、事件处理、动画制作以及Ajax交互。在本文中,我们将深入探讨jQuery API,了解其核心功能和常见用法,为您的前端开发工作提供有力的支持。 一...
4. **事件处理(Event Handling)** jQuery 提供了一种简化的事件处理方式。`.on()` 方法可以绑定各种事件,如点击('click')、鼠标悬停('hover')等。`.off()` 可以移除已绑定的事件。`$(document).ready()` 或...
例如,在事件处理方面,jQuery统一了不同浏览器下`event`对象的访问方式,无论是在IE还是其他浏览器中,都可以使用`event.target`来获取触发事件的对象。 ##### 3. 实现丰富的UI效果 除了基本的功能实现外,jQuery...
jQuery是JavaScript库中的一个巨无霸,自2006年发布以来,它极大地简化了DOM操作、事件处理、动画制作以及Ajax交互等任务,使得前端开发变得更加高效和简洁。jQuery-3.2.1版本是该库的一个重要迭代,虽然当前可能在...
3. **事件处理**:jQuery的事件处理非常灵活,如`click()`、`mouseover()`、`mouseout()`等,源码中会展示如何绑定和解绑事件,以及使用`event.preventDefault()`和`event.stopPropagation()`控制事件行为。...
10. **自定义事件**:开发者可以创建自定义事件,通过 `.triggerHandler()` 触发并处理这些事件,实现模块化和解耦代码。 **五、性能优化** 11. **DOM 优化**:减少 DOM 操作次数,避免不必要的遍历和修改,利用 `...