Upload
fangdeng
View
465
Download
5
Embed Size (px)
Citation preview
jQuery使用技巧
大纲
• 简单的js书写规则
• jQ静态方法
• jQ实例方法
• DIP、OCP原则
• jQ选择器
简单的js书写规则
我一直在寻找一种简单并统一的方式书写JS。
从java,C#等多人协作开发语言获得的经验
• 语法严谨,没有太多的选择
– 类和方法的创建只有一种方式
– 没有任我们无限嵌套的closure(虽然可能会在java 7 中支持)
• 约定大于配置(convension over configuration)– 1. 类名和文件名一致
– 2. 构造方法和类名一致
– 3. 包名和目录名一致
– …
如果我们对JS书写进行规则上的限制, 且不削弱它的描述能力,它应该能够极大地提
高可读性,并且 更适合团队开发。
代码应该有结构,合适的位置写合适的代码
规则1. 名称:
一个文件一个主类(或单例), 类名和文件名一致,用于描述功能
包名和文件夹结构一致
module/widget/dialog.js FE.platform.winport.widget.Dialogmodule/widget/ui.js FE.platform.winport.widget.UImodule/widget/switchable.js FE.platform.winport.widget.Switchable
.widget.Switcher
.widget.PagingSwitcher
.widget.Tabs
module/diy/msg.js FE.platform.winport.diy.Msgmodule/diy/form-dialog FE.platform.winport.diy.FormDialog
page/diy/site/site-publish.js SitePublishpage/diy/site/switch-version SwitchVersion
page/diy/mod/mod-list-panel ModListPanel
2. 结构:
单例或多例类使用模板中的结构书写
顶层结构中只包含import语句,类(对象)定义语句, 名字空间声明语句
方法调用遵循向下规则
3. 访问控制:
非公共类, 不需要挂接在名字空间下
公共类, 私有方法以下划线为前缀
• 方法
在方法内部的函数,需要访问this, 则定义 var self = this, 并且此语句是var 语句的第一句。
如:
var self = this, // self = this放在var语句的第一句
ret = [],
a = 1;
代码体缩进不大于3层, Closure嵌套不大于2层
open: function() {
if (a === 1) {
for (var i = 0; i < 10; i++) {
if (b === 3) {
for (….) , <---- 请重构此方法, 让缩进<= 3层
}
}
}
}
test: function() {elm.click(function() {
var a = function() {var b = function() { // 超过2层, 请重构
}}
});}
方法尽量不超过一屏,否则请重构
winport.js 1个方法达到39行, 1个47行supplier-info.js 1个方法达到60行,其中注释和空格占了20行inplaceeditor.js 1个方法达到40行ui.js 2 个方法达到 40行(不过没有按这个规则书写,有方法内部有函数对象,所以比
较长)
company-name-handler 有1个方法达到60行 (里面有较大的数据结构)
有1个50行diy/header.js 有1个方法40行pages.js 有1个方法达到50行
• 类(或对象)如果太长,则需要重构(根据功能来划分)
如果切割类的定义, 下次再详细分享
静态方法
• $.each– 可以对数组或对象进行迭代
– this为当前项,可使用proxy改变this指向,
– return false相当于break
– 如果对this进行相等性或类型检测时, 需要注意,typeof this === ‘object’
new String(‘hello’) === ‘hello’ // false
new String(‘hello’) == ‘hello’ // true
建议: 使用带参数方式, 顺便为当前项取个好名字
• $.extend– 设置默认参数
– undefined值的项不会被复制
• $.proxy– $.proxy(context, name) 减少缩进层次
• $.ajax– 在script 调用返回302,IE78, FF会进入success函数, IE6会进入error函数,行为不一
致
– 在jsonp调用返回302时, IE678 FF都会进行error, 行为比较一致
总结:
在script调用时, 需要在success中进行数据检测, 因为有时候不一定正常返回
做出错处理时, 需要在success和error中同时做
在jsonp调用时, 行为一致, 在success中只做成功逻辑, 在error中做出错逻辑,
但在FF中会由于超时而产生一个js错误, 不影响功能
• $.param– array/object -> querystring
对于中文参数的script请求,使用$.paramSpecial(…
旺铺中只用到一次paramSpecial, 只用在搜索的url拼接中,因为搜索关键字中会出现中文
• $.serialize -> $.param($.serializeArray())
• $.serializeArray ->
*, name: ‘user’, value: ‘hello’-, , name: ‘pass’: ‘value’: ‘helo123’ -+
实例方法
• index(element),在1.4引入index(), index(selector), 认识一下
• eq(index), 请用elm.eq(0) 代替 $(elm[0])
• 当在一个作用域中两次以上操作同一selector, 请保存一个引用
• attr(function) – jQuery中在1.4版本后,有好多的setting方法支持function参数
• toggleClass(class, switch), toggle(fun1, fun2, fun3…)
• closest(expr)
• andSelf()
• end()
• event helpers: – click, mouseenter, submit… 通过bind实现的
– focusin / focusout 支持冒泡, 可以在delegate和live中使用
• one(type, func)• bind(type, func)
– 可一次绑定多个事件,API比较详细,可参考它
• trigger(event)• triggerHandler(event)
– 不触发浏览器默认行为
– 只针对第1个节点
– 不冒泡– 返回事件函数结果,而不是jQ对象
• live(type, handler)• delegate(selector, type, handler)
事件
什么时候使用自定义事件?
如何处理类(对象)之间的关系?
• 依赖倒置原则(DIP)
– “抽象不应依赖于细节,细节应该依赖于抽象。”
– 思考各种回调函数,是如何引入间接层来 反转 依赖的
jQuery#data的使用
• 存贮节点相关数据
• 配合html5 data标签使用
jQ选择器Sizzle
• 优先采用#id, name, tag, tag.class, class最好要有tag修饰
• Selector如果没有位置信息:
POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
那么将采用从右到左的顺序解析
如 li.item a span 首先查找页面中所有的span, 然后再过滤出a内部的部分,然后再过滤
出符合li.item的部分
在jQuery中,可以通过扩展 $.expr 对 Sizzle进行扩展
如何扩展?
• 开放封闭原则(Open-Closed principle)– “软件实体应该是可以扩展的,但是不可修改。“
例子
• jQuery的扩展
– 通过 $.extend 和 $.fn.extend扩展, 不需要修改原代码
– Sizzle的扩展也非常方便, 通过Sizzle.selectors进行扩展
• 侧边栏广告位
• tracelog.js
• instantvalidator.js
• sign.js
• 数据结构是静止的算法 & 申明式编程
• OCP是一个目标
– 面对变化时,我们修改代码, 改完之后,面对同类变化, 我们以添加代码的方式
完成扩展, 而不需要修改原来的代码
– 受一次伤原理
– 不预测需求,只完成现有需求并符合OCP, 变化时才修改代码