jQuery库是一个很强大的js库,其中它容许自己对其扩展,做一些自己的插件来实现一些特定的功能,但是其插件开发一些规范性有以下几点需要注意的:
PS:以下内容参考于jQuery插件开发
1. 使用闭包:
(function($) { // Code goes here })(jQuery);
a) 避免全局依赖。
b) 避免第三方破坏。
c) 兼容jQuery操作符'$'和'jQuery '
其相当于如下:
var jq = function($) { // Code goes here }; jq(jQuery);
2. 扩展
jQuery提供了2个供用户扩展的‘基类’ - $.extend和$.fn.extend.
$.extend 用于扩展自身方法,如$.ajax, $.getJSON等,$.fn.extend则是用于扩展jQuery类,包括方法和对jQuery对象的操作。为了保持jQuery的完整性,我比较 趋向于使用$.fn.extend进行插件开发而尽量少使用$.extend.
3. 选择器
jQuery提供了功能强大,并兼容多种css版本的选择器,不过发现很多同学在使用选择器时并未注重效率的问题。
a) 尽量使用Id选择器,jQuery的选择器使用的API都是基于getElementById或getElementsByTagName,因此可以知道 效率最高的是Id选择器,因为jQuery会直接调用getElementById去获取dom,而通过样式选择器获取jQuery对象时往往会使用 getElementsByTagName去获取然后筛选。
b) 样式选择器应该尽量明确指定tagName, 如果开发人员使用样式选择器来获取dom,且这些dom属于同一类型,例如获取所有className为jquery的div,那么我们应该使用的写法 是$('div.jquery')而不是$('.jquery'),这样写的好处非常明显,在获取dom时jQuery会获取div然后进行筛选,而不是 获取所有dom再筛选。
c) 避免迭代,很多同学在使用jQuery获取指定上下文中的dom时喜欢使用迭代方式,如$('.jquery .child'),获取className为jquery的dom下的所有className为child的节点,其实这样编写代码付出的代价是非常大 的,jQuery会不断的进行深层遍历来获取需要的元素,即使确实需要,我们也应该使用诸如$(selector,context), $('selector1>selector2'), $(selector1).children(selector2), $(selctor1).find(selector2)之类的方式。
下面来看下jQuery的滑块插件:
如图:
插件写好之后,最终页面代码如下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <title>Untitled Document</title> <script type="text/javascript" src="jquery-1.2.6.js"></script> <script type="text/javascript" src="jquery.jslider.js"></script> <style type="text/css"> .defaultbar { margin-top: 10px; height: 5px; background-color: #FFFFE0; border: 1px solid #A9C9E2; position: relative; } .defaultbar .jquery-completed { height: 3px; background-color: #7d9edb; top: 1px; left: 1px; position: absolute; } .defaultbar .jquery-jslider { height: 15px; background-color: #E6E6FA; border: 1px solid #A5B6C8; top: -6px; display: block; cursor: pointer; position: absolute; } .defaultbar .jquery-jslider-hover { background-color: #000080; } fieldset { border: solid 1px #dedede; padding: 0 10px; } fieldset legend { background-color: #FFF5FA; border: 1px solid #F8B3D0; padding: 5px 10px; } </style> <script type="text/javascript"> $().ready(function(){ var maxFont = 30; var mf = $('#myFont').css('font-size', 30); $.fn.jSlider({ renderTo: '#slidercontainer1', size: { barWidth: 400, sliderWidth: 5 }, onChanging: function(percentage, e){ mf.css('font-size', maxFont * percentage); //在控制台输出信息 window.console && console.log('percentage: %s', percentage); } }); }); </script> </head> <body> <fieldset> <dl> <div id="myFont"> Hello, world! </div> <div id="slidercontainer1"> </div> </dl> </fieldset> </body> </html>
插件代码:
(function($){ $.extend($.fn, { /*实现一个jquery滑动条插件*/ jSlider: function(setting){ var ps = $.extend({ renderTo: $(document.body), enable: true, initPosition: 'max', size: {barWidth: 200,sliderWidth: 5}, barCssName: 'defaultbar', completedCssName: 'jquery-completed', sliderCssName: 'jquery-jslider', sliderHover: 'jquery-jslider-hover', onChanging: function(){ }, onChanged: function(){ } }, setting); //强制将renderTo强制转换成jQuery对象 ps.renderTo = (typeof ps.renderTo == 'string' ? $(ps.renderTo) : ps.renderTo); //渲染UI var sliderbar = $('<div><div> </div><div> </div></div>') .attr('class', ps.barCssName) .css('width', ps.size.barWidth) .appendTo(ps.renderTo); var completedbar = sliderbar.find('div:eq(0)') .attr('class', ps.completedCssName); var slider = sliderbar.find('div:eq(1)') .attr('class', ps.sliderCssName) .css('width', ps.size.sliderWidth); var bw = sliderbar.width(), sw = slider.width(); ps.limited = {min: 0, max: bw - sw}; //定位completedbar的填充长度以及slider左侧距离 if (typeof window.$sliderProcess == 'undefined') { window.$sliderProcess = new Function('obj1', 'obj2', 'left', 'obj1.css(\'left\',left);obj2.css(\'width\',left);'); } //eval('ps.limited.' + ps.initPosition)来获取,从而避免switch操作 //此处相当于调用 sliderProcess(xx,xx,xxx) 执行slider.css('left',value);completedbar.css('left',value) $sliderProcess(slider, completedbar, eval('ps.limited.' + ps.initPosition)); /*jQuery拖拽功能*/ var slide = { drag: function(e){ var d = e.data; var l=Math.min(Math.max(e.pageX - d.pageX + d.left, ps.limited.min), ps.limited.max); $sliderProcess(slider,completedbar,l); ps.onChanging(l/ps.limited.max,e); }, drop:function(e){ slider.removeClass(ps.sliderHover); ps.onChanged(parseInt(slider.css('left'))/ps.limited.max,e); //去除绑定 $().unbind('mousemove',slide.drag).unbind('mouseup',slide.drop); } }; // jSlider enable属性为true时,在end-user按下鼠标时绑定mousemove事件,在鼠标弹起时移除,我们只需要同步更新slider的left 属性和completedbar的width即可,同时在drag中绑定onChanging方法,在drop中绑定onChanged方法,向这两个方法推送的参数相同,1>百分比,即value值,介于0~1,2>event。 if(ps.enable){ slider.bind('mousedown',function(e){ var d={ left:parseInt(slider.css('left')), pageX:e.pageX } $(this).addClass(ps.sliderHover); $().bind('mousemove',d,slide.drag).bind('mouseup',d,slide.drop); }); } slider.data = { bar: sliderbar, completed: completedbar }; return slider; } }); })(jQuery);