第8章 高效开发和使用插件 (三)

简介: 8.1.13 优化 jQuery 插件 -- 添加事件日志 在传统开发中,软件都包含有事件日志,这样就可以在事件发生时或发生后进行跟踪。在 JavaScript 程序调试中,我们常常使用 alert() 方法来跟踪进程,但是这种做法影响了程序的正常流程,不符合频繁、实时显示事件信息。

8.1.13 优化 jQuery 插件 -- 添加事件日志

在传统开发中,软件都包含有事件日志,这样就可以在事件发生时或发生后进行跟踪。在 JavaScript 程序调试中,我们常常使用 alert() 方法来跟踪进程,但是这种做法影响了程序的正常流程,不符合频繁、实时显示事件信息。我们可以模仿其他软件中的调试台 log() 函数,借助这个函数将事件日志信息输出到独立的日志文件中,从而避免中断页面交互进程。

首先,我们为 jQuery 对象添加一个全局函数 log() 。在这个函数中,将把发生的事件信息写入事件日志包含框中。实现代码如下。

[html] view plain copy
  1. jQuery.log=function(msg){
  2. varhtml=jQuery('<divclass="log"></div>').text(msg);
  3. jQuery(".logbox").append(html);
  4. };
然后,在事件中调用该日志方法,从而实时跟踪事件发生时的事件,实现代码如下。

[html] view plain copy
  1. <scripttype="text/javascript">
  2. jQuery.log=function(msg){
  3. varhtml=jQuery('<divclass="log"></div>').text(msg);
  4. jQuery(".logbox").append(html);
  5. };
  6. $(function(){
  7. $("input").click(function(event){
  8. vare=event.type;
  9. $.log(e);
  10. });
  11. $("input").mouseover(function(event){
  12. vare=event.type;
  13. $.log(e);
  14. });
  15. $("input").mouseout(function(event){
  16. vare=event.type;
  17. $.log(e);
  18. });
  19. });
  20. </script>
  21. </head>
  22. <body>
  23. <inputtype="button"value="提交按钮"/>
  24. <divclass="logbox"></div>
  25. </body>
但是,在一个页面中往往会包含很多事件示例,如果分别进行记录,会非常不方便,为此可以定义一个对象方法,而不是使用全局函数。代码如下所示。

[html] view plain copy
  1. (function($){
  2. $.extend($.fn,{
  3. log:function(msg){
  4. varhtml=jQuery('<divclass="log"></div>').text(msg);
  5. returnthis.each(function(){
  6. jQuery(".logbox").append(html);
  7. });
  8. }
  9. });
  10. })(jQuery);
然后在实例中调用该日志方法,代码如下。

[html] view plain copy
  1. <scripttype="text/javascript">
  2. (function($){
  3. $.extend($.fn,{
  4. log:function(msg){
  5. varhtml=jQuery('<divclass="log"></div>').text(msg);
  6. returnthis.each(function(){
  7. jQuery(".logbox").append(html);
  8. });
  9. }
  10. });
  11. })(jQuery);
  12. $(function(){
  13. $("h1").click(function(event){
  14. vare=event.type;
  15. $(this).log(this.nodeName.toLowerCase()+"."+e);
  16. });
  17. $("p").mouseover(function(event){
  18. vare=event.type;
  19. $(this).log(this.nodeName.toLowerCase()+"."+e);
  20. });
  21. $("input").mouseout(function(event){
  22. vare=event.type;
  23. $(this).log(this.nodeName.toLowerCase()+"."+e);
  24. });
  25. });
  26. </script>
  27. </head>
  28. <body>
  29. <h1>标题文本</h1>
  30. <inputtype="button"value="提交按钮"/>
  31. <p>段落文本</p>
  32. <divclass="logbox"></div>
  33. </body>
我们还可以进一步改善 log() 日志方法的灵活度,使其自动搜索最近显示日志信息的元素,通过利用该方法的语境,我们可以在遍历 DOM 元素时找到距离最近的日志元素。实现代码如下。

[html] view plain copy
  1. <scripttype="text/javascript">
  2. (function($){
  3. $.extend($.fn,{
  4. log:function(msg){
  5. returnthis.each(function(){
  6. var$this=$(this);//获取当前元素
  7. while($this.length){//如果存在当前元素
  8. var$logbox=$this.find(".logbox");//在当前元素内搜索是否存在日志元素
  9. if($logbox.length){//如果存在日志元素
  10. varhtml=jQuery('<divclass="log"></div>').text(msg);
  11. $logbox.append(html);
  12. break;//跳出检索
  13. }
  14. $this=$this.parent();//检索上一级匹配元素
  15. }
  16. });
  17. }
  18. });
  19. })(jQuery);
  20. $(function(){
  21. $("h1").click(function(event){
  22. vare=event.type;
  23. $(this).log(this.nodeName.toLowerCase()+"."+e);
  24. });
  25. $("p").mouseover(function(event){
  26. vare=event.type;
  27. $(this).log(this.nodeName.toLowerCase()+"."+e);
  28. });
  29. $("input").mouseout(function(event){
  30. vare=event.type;
  31. $(this).log(this.nodeName.toLowerCase()+"."+e);
  32. });
  33. });
  34. </script>
  35. </head>
  36. <body>
  37. <h1>标题文本</h1>
  38. <inputtype="button"value="提交按钮"/>
  39. <p>段落文本</p>
  40. <divclass="logbox"></div>
  41. </body>
最后,我们还可以改善参数的处理机制,考虑到 log() 方法只能够简单地接受字符串型信息,如果要向 log() 方法传递更多的信息,就会变得无能为力。遵循 jQuery 框架方法的一贯设计思想,我们可以考虑允许用户以对象列表的形式向 log() 方法传递更多甚至无限制的信息。因此,我们还需对 log() 方法中的参数处理机制进行改善。如果用户向其传入对象类型的参数,则直接调用它,将会显示 "[object object]" 的字符串,显然这并不是我们所希望的日志信息。

[html] view plain copy
  1. (function($){
  2. $.extend($.fn,{
  3. log:function(msg){
  4. if(typeofmsg=="object"){//如果参数为对象类型,则解析该对象包含的信息
  5. varstr="{";
  6. $.each(msg,function(name,value){//遍历对象成员
  7. str+=name+":"+value+",";
  8. });
  9. str=str.substring(0,str.length-2);//消除最后一个成员的逗号
  10. str+="}";
  11. msg=str;//把解析的对象信息返回给参数变量
  12. }
  13. returnthis.each(function(){
  14. var$this=$(this);//获取当前元素
  15. while($this.length){//如果存在当前元素
  16. var$logbox=$this.find(".logbox");//在当前元素内搜索是否存在日志元素
  17. if($logbox.length){//如果存在日志元素
  18. varhtml=jQuery('<divclass="log"></div>').text(msg);
  19. $logbox.append(html);
  20. break;//跳出检索
  21. }
  22. $this=$this.parent();//检索上一级匹配元素
  23. }
  24. });
  25. }
  26. });
  27. })(jQuery);
这样,我们就可以在 log() 方法中传入更多的信息,当然也可以直接传入字符串信息,应用示例如下所示。

[html] view plain copy
  1. $(function(){
  2. $("h1").click(function(event){
  3. $(this).log({
  4. nodeName:this.nodeName.toLowerCase(),
  5. eventType:event.type
  6. });
  7. });
  8. $("p").mouseover(function(event){
  9. $(this).log({
  10. nodeName:this.nodeName.toLowerCase(),
  11. eventType:event.type
  12. });
  13. });
  14. $("input").mouseout(function(event){
  15. vare=event.type;
  16. $(this).log(this.nodeName.toLowerCase()+"."+e);
  17. });
  18. });
  19. </script>
  20. </head>
  21. <body>
  22. <h1>标题文本</h1>
  23. <inputtype="button"value="提交按钮"/>
  24. <p>段落文本</p>
  25. <divclass="logbox"></div>
  26. </body>

8.1.14 创建 jQuery 插件应注意的问题

由于插件结构简单,创建比较容易,对于初学者来说它简单易学,对于高手来说它很灵活,因此网上共享的 jQuery 插件数量急速上升。另外,jQuery 允许使用多种风格创建插件,如何遵守公共规则,是很多初学者必须注意的问题。

jQuery 开发团队制定了通用规则,为插件用户创建了一个通用而可信的环境。因此,建议读者在创建插件中遵守这些规则,确保自定义的插件与其他代码和平相处,并获得广大用户的认可。

创建 jQuery 插件应注意以下几个问题。

1.命名规则

如果希望用户查看文件时能立即知道这是一个什么插件,统一文件名称是必须的。我们可以遵循这样的命名规则: jquery.plug-in_name.js 。

其中 plug-in_name 表示插件的名称,在这个文件中,所有全局函数都应该包含在名为 plug-in_name 的对象中。如果插件只有一个函数,则可以考虑使用 jQuery.plug-in_name() 形式命名。

插件中的对象方法可以灵活命名,但是应保持相同的命名风格。如果定义多个方法,建议在方法名前添加插件名前缀,以保存清晰。不建议使用过于简短的名称,或者语义含糊的缩写名,或者公共方法名,如 set() 、get() 等,这样很容易与外界的方法混淆。

2.基本思想

所有新方法都附加到 jQuery.fn 对象上,所有新功能都附加到 jQuery 对象上。这是实际编码过程中最重要的规则。

3.方法内的 this 关键字

在插件方法中,this 关键字用于引用 jQuery 对象,这有利于插件编写,它让所有插件在引用 this 时,知道从 jQuery 接收到哪个对象。所有 jQuery 方法都是一个 jQuery 对象的环境中调用的,因此函数体中 this 关键字总是指向该函数的上下文,即 this 此时是一个包含多个 DOM 元素的数组。

4.迭代匹配元素

使用 this.each() 迭代匹配的元素,这是一种可靠而有效地迭代对象的方式。

出于性能和稳定性考虑,推荐所有的方法都使用它迭代匹配的元素。无论 jQuery 对象实际匹配的元素有多少,所有方法都必须以适当方式运行,一般来说,应该调用 this.each() 方法来迭代所有匹配的元素,然后再依次操作每个 DOM 元素。

****注意:在 this.each() 方法体内,this 关键字就不再引用 jQuery 对象,而是引用当前匹配的 DOM 元素对象。****

5.方法返回值。

所有方法都应该返回一个值,除了特定需求方法外,所有方法都必须返回 jQuery 对象。

除了需要方法返回计算值或者某个特定对象等,一般方法都应该返回当前上下文环境中的 jQuery 对象,即 this 关键字引用的数组。通过这种方式,可以保持 jQuery 框架内方法的连续行为,即方法连缀写法。jQuery 方法的顺序链非常著名,如果编写打破链条的插件,它就会给用户开发带来诸多不方便。

如果匹配的对象集合被修改,则应该通过调用 pushStack() 方法创建新的 jQuery 对象,并返回这个新对象,如果返回值不是 jQuery 对象,则应该明确说明。

6.方便压缩

插件中定义的所有方法或函数,在末尾都必须加上分号(即 ;) ,以方便代码压缩。压缩 JavaScript 文件是最佳实践,若大于最小值会让自定义插件很快就被用户抛弃。

7.jQuery 和 $ 有区别

在插件代码中总是使用 "jQuery" ,而不是 "$" 。$ 并不总是等于 jQuery ,这个很重要,如果用户使用 var JQ = jQuery.noConflict() ;函数更改 jQuery 别名,那么就会引发错误,另外其他 JavaScript 框架也可能使用 $ 别名。

在复杂的插件中,如果全部使用 "jQuery" 代替 "$" ,又会让人难以接受这种复杂的写法,为了解决这个问题,建议使用如下插件模式。

(function($){

// 在插件包中使用 $ 代替 jQuery

})(jQuery);

这个包装函数接受一个参数,该参数传递的是 jQuery 全局对象,由于参数被命名为 $ ,因此在函数体内就可以安全使用 $ 别名,而不用担心命名冲突。

上述这些规则在插件代码中都必须遵守,如果不遵守这些插件规则,那么自己开发的插件就得不到广泛应用和推广。因此,遵守这些规则非常重要,它不仅能保证插件代码的统一性,还能增加插件的成功几率。

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
9月前
|
存储 缓存 移动开发
构建跨平台应用的利器——UniApp入门指南
构建跨平台应用的利器——UniApp入门指南
|
9月前
|
Web App开发 前端开发 JavaScript
从开发chrome插件到插件系统设计
最近ChatGPT的技术概念很火热,开发了一个node-gptcommit开源项目,主要利用GPT用来自动生成git commit的信息。
217 0
|
11月前
|
前端开发
《智能前端技术与实践》——第1章 开发环境配置——1.5 使用 WebStorm
《智能前端技术与实践》——第1章 开发环境配置——1.5 使用 WebStorm
|
11月前
|
前端开发 Devops API
前端利器躬行记(8)——VSCode插件研发
前端利器躬行记(8)——VSCode插件研发
|
移动开发 前端开发 weex
uniapp调试基座安装与移动端应用选型
uniapp调试基座安装与移动端应用选型
uniapp调试基座安装与移动端应用选型
|
敏捷开发 开发框架 Java
鲲鹏系列四: DevKit开发框架插件工具技术要点总结
鲲鹏应用开发面临问题主要包含以下三方面: 开发:缺乏鲲鹏亲和开发的实时引导;缺乏对鲲鹏特点的检查工具;依赖库生态难以快速获取。 编译调试:难以充分利用微架构性能优势;无多样算力编译和调试能力。 测试:兼容性测试工作量大;应用的安全性、稳定性、性能及功耗等问题难以保障。
349 0
 鲲鹏系列四: DevKit开发框架插件工具技术要点总结
|
资源调度 前端开发
主流脚手架工具介绍
主流脚手架工具介绍
321 0
|
缓存 监控 数据可视化
技术调研,IDEA 插件怎么开发「脚手架、低代码可视化编排、接口生成测试」?
前言 二、抛出问题 三、开发插件涉及的问题 四、开发插件的两种配置 1. 基础配置 2. 遇到问题 五、写个测试案例 1. 工程结构 2. AnAction 3. MyToolWindowFactory 4. plugin.xml 5. 测试结果 六、插件开发能做啥都 1. 快速生成 CRUD 工程代码 2. 在 IDEA 中摸鱼聊天 3. 可视化流程编排 七、总结 八、系列推荐
589 0
技术调研,IDEA 插件怎么开发「脚手架、低代码可视化编排、接口生成测试」?
|
Web App开发 JSON 缓存