Model层的诞生-开发WebOS(三)

By | 2013年12月15日

昨天一个人跑到公司敲代码,虽然环境和22寸的屏幕对我很有吸引力,不过周末不给开空调腿很冷的,今天就在家继续coding了。

晚上回到家,吃过晚饭,公园散步时一直在思考开发webos遇到的问题以及接下来要完善的功能,最后确定下来,先完成窗体的拖放功能,之所以先完成这个功能是因为,自己不想使用网络上现有的拖放插件,打算自己动手写一个,不仅可以理解原理,也可以熟悉jQuery插件开发的流程,想到这点后马上回家coding了。

关于拖放,之前自己写过拖放,原理不复杂,拖动元素必须是绝对定位,主要用到的事件是 mousedown(), mousemove(), mouseup() , 同时还需要个canMove 标记是否拖放的状态,
1. mousedown()事件中主要记录下鼠标点击时,鼠标相对于拖放元素内部的坐标并将canMove标记设为true。
2. mousemove()事件中记录鼠标的偏移量并改变拖放容器的top和left属性。
3. mouseup()事件中将 canMove设为false.拖放结束。
参考博友的文章:<JQuery之拖拽插件>

在此插件开发过程中遇到的问题:
1. offset() 和position() 竟然搞混了。
offset() :在匹配的元素集合中,获取的第一个元素的当前坐标,或设置每一个元素的坐标,坐标相对于文档。
position() :获取匹配元素中第一个元素的当前坐标,相对于offset parent的坐标。
2.快速移动鼠标,就会出现div跟不上鼠标的现象
这个问题产的原因是因为,鼠标移动速度很快,超出了移动容器的范围后,容器不在移动,鼠标离开了容器的范围所以mousemove()事件不在继续执行了。我是用的解决方式是对document对象上监听mousemove()事件。
3.jQuery插件开发时,注意$.fn.FunctionName 和$.FunctionName 的区别。
$.fn.FunctionName ,此时的FunctionName可以被jQuery元素对象调用。
$.FunctionName, 是全局函数,不能被jQuery元素调用。

拖放插件开发完,就一直在思考代码组织的问题,之所以思考这个问题是因为感觉自己现在代码很乱。组织方式如下:
2
这种写法,其实就相当于定义了不同事件的命名空间而已,可是随着方法的增多,这里就会显得混乱,比如说,icon的事件,icon窗体的事件,仅仅是命名空间来区分还是会感觉很乱,里面不仅有元素创建,事件绑定,元素的控制等等,所有的事件控制全部写在这里了。我自己预感这个YxjOSCore会越来越臃肿。

所以脑海里总是想着分离,临睡前看到桌子上的mvc的书,灵光一闪,mvc讲究关注分离,同时想起了面向对象编程,因为自己偏后端开发,这些经常用的东西,放在Js里竟然一下没有想起来,不禁汗颜,同时也因为自己找到了解决思路而高兴,如不是半夜12点多了,真想爬起来马上实践一下了。

今天早上一醒来,就开始分析如何对目前的结构抽象出对象,首先想到的是窗体,因为每个图标都会打开新的窗口;然后是图标也可抽离成一个对象。 既然是对象了那么接下来就容易很多了。代码备份了一份,立刻开始重构代码了,新的代码中,增加一个model.js专门用来存储对象,原来的core.js专门作为调用对象的控制层。

如此一来代码结构就比之前清晰了.core.js只要专注开发控制对象就可以了,对象自己内部维护自己的创建、事件绑定,对于特定的事件只要公布出回调函数公布出来,core.js就能调用了。

抽离出的windowModel示例:
1
这次的重构,也让自己感觉到js的强大以及超强的灵活性,也让自己意识到时刻要用面向对象的思路去看待问题。

总结一下重构学到的知识:
1. js中的oop (参考资料:js面向对象编程)
js中对象的创建方式有很多种,有构造函数式定义,原型式类定义, json式定义。我自己使用的是构造函数式,这点跟C#创建类很像,用起来熟悉。

2. this对象的理解
对this对象有了明确的理解,细心的朋友,应该会注意到上面的代码片段中定义的_self变量,这个变量是解决jQuery函数里this 引用问题。
3. call 方法的使用 (参考资料:js call)

call方法的使用很好的对外提供了回调函数机制。 call方法还有其他用法,比如:可以让a对象来执行b对象的方法。

在线测试地址:http://www.yuanxj.net/YOS/index.html

发表评论