更新时间:2018年12月07日13时17分 来源:传智播客 浏览次数:
# jQuery自定义插件开发实践 ## JavaScript插件是什么?
我们写代码,有一个很重要的原则就是“避免重复造轮子”,我们得看一下是否需要将一部分经常重复的代码抽象出来,写到一个单独的文件中便于以后再次使用。所谓JavaScript插件就是那些已经写好的可以极大提高自己代码质量或者页面展示效果的JavaScript文件(JavaScript代码片段/函数),之所以叫做插件,那么就是开箱即用,或者我们只要添加一些配置参数就可以达到我们需要的结果。 ## JavaScript插件的思想 * 封装复用 ”复用”是使用JavaScript插件的目的,“封装”是实现JavaScript插件的方法 * 开箱即用 所谓“开箱即用”,指的就是插件引入到工程中之后,直接使用或者配置一些参数就可以达到我们需要的结果 * 可插拔 插件是以JavaScript文件的形式提供的,使用的时候引入JavaScript文件,不需要的时候注释调用代码即可,实现可插拔 * 易维护插件是被封装的插件,一次封装多处使用,需要修改或者变更的时候,可以直接修改插件本身,易于维护 ## 关于jQuery插件 jQuery是一款非常优秀的开源JavaScript框架,封装JavaScript插件时不仅可以基于原生的JavaScript实现,也可以更方便地基于jQuery框架实现。
要说jQuery最为成功的地方,笔者认为是它的可扩展性吸引了全球众多的开发者为其开发插件,从而建立起了一个jQuery生态系统。相信读者肯定也使用或者熟悉了不少jQuery插件,比如jQuery通知插件Noty,比如非常有名的jQuery zTree树插件、jQuery上传插件Uploadify、操作Cookie的jQuery-Cookie插件、还有很多其他非常炫酷的插件等等。毫不夸张地说,jQuery插件对Web应用产生了重大的影响。 开发人员如果想将能力上升一个台阶,那么编写一个属于自己的jQuery插件是个不错的选择,接下来笔者会介绍如何开发自定义jQuery插件,并示例给读者。 ## jQuery插件开发模式 所谓模式,说白了就是套路,但这种套路是前人优秀开发经验的总结,学习并使用模式可以让我们更快、更好、更优雅的编写、组织代码。
jQuery提供了三种插件开发模式,基于这三种模式我们可以自定义封装jQuery插件
三种模式如下:
* **模式一:**通过$.extend()来扩展jQuery
* **模式二:**通过$.fn 向jQuery添加新的方法
* **模式三:**通过$.widget()应用jQuery UI的部件工厂方式创建 第三种模式是用于开发jQuery高级部件的,该模式开发出来的部件带有很多jQuery内建的特性,比如插件的状态等,一般使用场景下用不到这种模式,本文不再细说。
第一种模式简单些,仅仅是在jQuery命名空间或者可以理解为在jQuery身上添加了一个静态方法而已,所以我们调用通过\$.extend()开发的插件(添加的函数)时,我们直接通过\$符号调用(\$.myFunction())而不需要选中DOM元素(\$("#id").myFunction()),注意这里的myFunction指的是你自己定义的函数名。
请看下面的例子 ```html ```
运行结果如下:
如上就是基于\$.extend()模式自定义的一个简单jQuery插件,这个插件给jQuery扩展了一个sayWelcome函数,然后可以通过\$直接调用。如同读者所见,基于此模式开发一些辅助性的功能插件还是比较方便的,但这种模式没有办法利用jQuery强大选择器带来的便利,如果要处理DOM元素并将插件较好地运用在所选择的元素身上,那么还是需要使用第二种模式来开发jQuery插件,我们通常见到或者使用的插件大多也是通过这种模式开发的。
接下来,笔者基于第二种模式来开发一个自定义的jQuery高亮插件并将其命名为:jqHighlight,该插件支持在页面某个元素内搜索某个关键词并高亮关键词,高亮样式可以重新定义(高亮字体大小、高亮背景色),支持右上角标显示(角标可用于显示解释内容或者错误词汇所对应的正确词汇等),右上角标样式也可以重新定义。
## 示例:开发自定义jQuery高亮插件jqHighlight * **jqHighlight插件效果实现思路** 1)关键词搜索及高亮实现思路遍历对象范围内的各个DOM元素节点,使用正则表达式匹配,若匹配到关键词,则在关键词外包装一层标签,后续高亮效果的实现都是对标签的操作 2)右上角标实现思路 在包装关键词的标签内填充一个标签,通过样式控制标签显示在高亮关键词的右上角 - **定义插件** jqHighlight插件实际包括两部分:高亮和清除高亮。所以可以认为该插件由两个小插件组成,定义如下 ```js // 高亮 $.fn.jqHighlight = function (words, options) { // 插件实现 }; // 清除高亮 $.fn.jqHighlightClear = function (options) { // 插件实现 }; ``` jqHighlight可以传入两个参数,words参数是需要搜索的关键词,options是设置自定义参数的对象(后续会介绍到);jqHighlightClear主要用于清除高亮效果 - **插件中自定义参数的处理** 一般情况下,在插件内部设置默认参数,实际使用的时候,如果传入有自定义参数就覆盖插件的默认参数,使用$.extend将自定义参数和默认参数合并 ```js var settings = { className: 'highlight', // 命中关键词的显示样式,传入css样式类名,可以在插件外部定义该样式的具体属性,比如高亮字体大小、高亮背景色 supClassName:'sup', // 右上角标css样式类名 caseSensitive: false, // 搜索关键词时是否大小写敏感,默认不敏感 suptext:'' // 标注内容,比如搜索错别字的时候可以在右上角标显示正确的字 }; // extend方法会把options中重新定义的参数覆盖到settings中,形成新的settings $.extend(settings, options); ``` - **jqHighlight插件代码片段一** ```js $.fn.jqHighlight = function (words, options) { var settings = { className: 'highlight', // 命中关键词的显示样式,传入css样式类名,可以在插件外部定义 该样式的具体属性,比如高亮字体大小、高亮背景色 supClassName:'sup', // 右上角标css样式类名 caseSensitive: false, // 搜索关键词时是否大小写敏感,默认不敏感 suptext:'' // 标注内容,比如搜索错别字的时候可以在右上角标显示正确的字 }; // 使用自定义参数覆盖默认参数 $.extend(settings, options); if (words.constructor === String) { words = [words]; } // 过滤搜索关键词中的空元素 words = $.grep(words, function(word, i){ return word != ''; }); // 将搜索关键词中的特殊字符转义 words = $.map(words, function(word, i) { return word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); }); if (words.length == 0) { return this; }; // 根据搜索时是否配置了大小写敏感参数调整正则表达式 var flag = settings.caseSensitive ? "" : "i"; var pattern = "(" + words.join("|") + ")"; var re = new RegExp(pattern, flag); // 使用JavaScript正则表达式在对象范围内的元素中搜索关键词,搜索到之后进行高亮及右上角标处理 return this.each(function () { // 使用第一种模式jQuery.extend的方式将jqHighlight插件的核心处理逻辑封装为了辅助插件, 见后续介绍
$.highlight(this, re,settings.className, settings.supClassName,settings.suptext); }); }; ``` - **jqHighlight插件代码片段二** 使用第一种模式jQuery.extend的方式将jqHighlight插件的核心处理逻辑封装为了辅助插件,如下 ```js $.extend({ highlight: function (node, re, className,supClassName,suptext) { // DOM元素的节点属性,3代表元素或属性中的文本内容 if (node.nodeType === 3) { var match = node.data.match(re); if (match) { var highlight = document.createElement('span'); highlight.className = className || 'highlight'; var wordNode = node.splitText(match.index); wordNode.splitText(match[0].length); var wordClone = wordNode.cloneNode(true); highlight.appendChild(wordClone); wordNode.parentNode.replaceChild(highlight, wordNode); // 根据是否有传入右上角标内容添加右上角标显示 if(suptext != null && $.trim(suptext).length>0) { $(highlight).css("position","relative"); $(highlight).append("" + suptext + ""); } } // 若没有找到文本内容,钻取处理 } else if ((node.nodeType === 1 && node.childNodes) && !/(script|style)/i.test(node.tagName) && !(node.tagName === 'SPAN' && node.className === className)) { for (var i = 0; i < node.childNodes.length; i++) { $.highlight(node.childNodes[i],re,className,supClassName,suptext); } } } }); ``` - **jqHighlightClear插件代码片段** 高亮效果生成以后,有时我们需要清除高亮效果,只要找到我们在做高亮效果时包装的span标签,然后把span标签remove掉保留其中的内容就可以了。实现代码如下 ```js $.fn.jqHighlightClear = function (options) { var settings = { className: 'highlight' }; jQuery.extend(settings, options); return this.find("span." + settings.className).each(function () { var parent = this.parentNode; parent.replaceChild(this.firstChild, this); parent.normalize(); }); }; ``` **注意:**jqHighlightClear使用时需要根据情况传入className参数,这个参数应当和使用jqHighlight时设置的className属性保持一致,如果默认都默认即可,因为你的页面元素中可能用于其他用途的span,而我们要remove的是我们包装上去的拥有特定className的那些,remove时会右上角标会一并清除。 - **测试代码** **Html** ```html
黑马程序员是传智播客旗下高端IT教育品牌,以务实、质量、创新、分享、专注、责任为核心价值观,致力于服务各大软件企业,解决当前软件开发技术飞速发展,而企业招不到优秀人才的困扰。目前,“中关村黑马程序员训练营”已成长为行业“学员质量好、课程内容深、企业满意”的移动开发高端训练基地,并被评为中关村软件园重点扶持人才企业。黑马程序员不仅着重培养学员的基础理论知识,更注重培养项目实施管理能力,并密切关注技术革新,不断引入先进的技术,研发更新技术课程,确保学员进入企业后不仅能独立从事开发工作,更能给企业带来新的技术体系和理念。黑马程序员的学员多为大学毕业后,想从事IT行业,但各方面条件还不成熟的年轻人。黑马程序员的学员筛选制度非常严格,包括了严格的技术测试、自学能力测试,还包括性格测试、压力测试、品德测试等。百里挑一的残酷筛选制度确保了学员质量,并降低了企业的用人风险。一直以来,黑马程序员的教学研发团队一直致力于打造精品课程资源,不断在产、学、研三个层面创新自己的职教理念与教学方针,并集中黑马程序员的优势力量,有针对性的出版了计算机系列教材30多册,制作了配套教学视频数十套,并发表各类技术文章数百篇。 黑马程序员分享的免费视频教程累计时长10余万小时;率先在业内推出免费公开课,现已经开设700多节;印制现有学科的光盘,并且面向全国范围内免费给学员发放,累计发出去的光盘数量已经突破300万,通过免费提供的资源已经影响了近5000万IT爱好者。 黑马程序员始终秉承“为莘莘学子改变命运而讲课,为千万学生少走弯路而著书”的使命,以技术视角关注IT产业发展,以深度分享推进产业技术成长,致力于弘扬技术创新,倡导分享、开放和协作,努力打造高质量的IT人才服务平台。