`
kenshinlk
  • 浏览: 118362 次
  • 性别: Icon_minigender_1
  • 来自: 广东.佛山.南海
社区版块
存档分类
最新评论

prototype学习资料(三)

阅读更多
js 代码
  1. /**   
  2. * Form.Element.getValue 会经常用到,所以做了一个快捷引用   
  3. * 取得某个表单控件的值,可以简化调用为 $F("username"),真是方便啊   
  4. */    
  5. var $F = Form.Element.getValue;    
  6. /**   
  7. * Abstract.TimedObserver 也没有用 Class.create() 来创建,和Ajax.Base 意图应该一样   
  8. * Abstract.TimedObserver 顾名思义,是套用Observer设计模式来跟踪指定表单元素,   
  9. * 当表单元素的值发生变化的时候,就执行回调函数   
  10.  
  11. * 我想 Observer 与注册onchange事件相似,不同点在于 onchange 事件是在元素失去焦点的时候才激发。   
  12. * 同样的与 onpropertychange 事件也相似,不过它只关注表单元素的值的变化,而且提供timeout的控制。   
  13.  
  14. * 除此之外,Observer 的好处大概就在与更面向对象,另外可以动态的更换回调函数,这就比注册事件要灵活一些。   
  15. * Observer 应该可以胜任动态数据校验,或者多个关联下拉选项列表的连动等等   
  16.  
  17. */    
  18. Abstract.TimedObserver = function() {}    
  19. /**   
  20. * 这个设计和 PeriodicalExecuter 一样,bind 方法是实现的核心   
  21. */    
  22. Abstract.TimedObserver.prototype = {    
  23. initialize: function(element, frequency, callback) {    
  24. this.frequency = frequency;    
  25. this.element = $(element);    
  26. this.callback = callback;    
  27.   
  28. this.lastValue = this.getValue();    
  29. this.registerCallback();    
  30. },    
  31. registerCallback: function() {    
  32. setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);    
  33. },    
  34. onTimerEvent: function() {    
  35. var value = this.getValue();    
  36. if (this.lastValue != value) {    
  37. this.callback(this.element, value);    
  38. this.lastValue = value;    
  39. }    
  40. }    
  41. }    
  42. /**   
  43. * Form.Element.Observer 监视指定表单域的值是否变化   
  44. */    
  45. Form.Element.Observer = Class.create();    
  46. Form.Element.Observer.prototype = (new Abstract.TimedObserver()).extend({    
  47. getValue: function() {    
  48. return Form.Element.getValue(this.element);    
  49. }    
  50. });    
  51. /**   
  52. * Form.Element.Observer 监视指定表单所有控件的值是否有变化   
  53. */    
  54. Form.Observer = Class.create();    
  55. Form.Observer.prototype = (new Abstract.TimedObserver()).extend({    
  56. getValue: function() {    
  57. return Form.serialize(this.element);    
  58. }    
  59. });    
  60. /*--------------------------------------------------------------------------*/    
  61. /**   
  62. * EventObserver 相比上面的 TimedObserver,是更具主动性的一种监测   
  63. * 它直接为表单控件(根据 type 的不同) 注册相应的事件处理, 只要发现某个控件值发生改变,就执行回调函数   
  64. */    
  65. Abstract.EventObserver = function() {}    
  66. Abstract.EventObserver.prototype = {    
  67. initialize: function(element, callback) {    
  68. this.element = $(element);    
  69. this.callback = callback;    
  70.   
  71. this.lastValue = this.getValue();    
  72. if (this.element.tagName.toLowerCase() == 'form')    
  73. this.registerFormCallbacks();    
  74. else    
  75. this.registerCallback(this.element);    
  76. },    
  77. onElementEvent: function() {    
  78. var value = this.getValue();    
  79. if (this.lastValue != value) {    
  80. this.callback(this.element, value);    
  81. this.lastValue = value;    
  82. }    
  83. },    
  84. registerFormCallbacks: function() {    
  85. var elements = Form.getElements(this.element);    
  86. for (var i = 0; i < elements.length; i++)    
  87. this.registerCallback(elements);    
  88. },    
  89. registerCallback: function(element) {    
  90. if (element.type) {    
  91. switch (element.type.toLowerCase()) {    
  92. /**   
  93. * checkbox 和 radio 类型的控件注册 onclick 事件处理   
  94. */    
  95. case 'checkbox':    
  96. case 'radio':    
  97. element.target = this;    
  98. element.prev_onclick = element.onclick || Prototype.emptyFunction;    
  99. /**   
  100. * 相信这里有改进的空间,应该使用其后的 Event对象提供的注册管理功能来统一注册   
  101. */    
  102. element.onclick = function() {    
  103. this.prev_onclick();    
  104. this.target.onElementEvent();    
  105. }    
  106. break;    
  107. /**   
  108. * 其他类型的控件注册 onchange 事件处理   
  109. */    
  110. case 'password':    
  111. case 'text':    
  112. case 'textarea':    
  113. case 'select-one':    
  114. case 'select-multiple':    
  115. element.target = this;    
  116. element.prev_onchange = element.onchange || Prototype.emptyFunction;    
  117. element.onchange = function() {    
  118. this.prev_onchange();    
  119. this.target.onElementEvent();    
  120. }    
  121. break;    
  122. }    
  123. }    
  124. }    
  125. }    
  126. /**   
  127. * 监视指定表单控件   
  128. */    
  129. Form.Element.EventObserver = Class.create();    
  130. Form.Element.EventObserver.prototype = (new Abstract.EventObserver()).extend({    
  131. getValue: function() {    
  132. return Form.Element.getValue(this.element);    
  133. }    
  134. });    
  135. /**   
  136. * 监视指定表单所有控件   
  137. */    
  138. Form.EventObserver = Class.create();    
  139. Form.EventObserver.prototype = (new Abstract.EventObserver()).extend({    
  140. getValue: function() {    
  141. return Form.serialize(this.element);    
  142. }    
  143. });    
  144. /**   
  145. * 封装事件处理的静态工具对象   
  146. */    
  147. if (!window.Event) {    
  148. var Event = new Object();    
  149. }    
  150. Object.extend(Event, {    
  151. KEY_BACKSPACE: 8,    
  152. KEY_TAB: 9,    
  153. KEY_RETURN: 13,    
  154. KEY_ESC: 27,    
  155. KEY_LEFT: 37,    
  156. KEY_UP: 38,    
  157. KEY_RIGHT: 39,    
  158. KEY_DOWN: 40,    
  159. KEY_DELETE: 46,    
  160. element: function(event) {    
  161. return event.target || event.srcElement;    
  162. },    
  163. isLeftClick: function(event) {    
  164. return (((event.which) && (event.which == 1)) ||    
  165. ((event.button) && (event.button == 1)));    
  166. },    
  167. /**   
  168. * click事件时鼠标以页面为基准的x坐标值, 考虑到了滚动条导致的位移差   
  169. */    
  170. pointerX: function(event) {    
  171. return event.pageX || (event.clientX +    
  172. (document.documentElement.scrollLeft || document.body.scrollLeft));    
  173. },    
  174. /**   
  175. * click事件时鼠标以页面为基准的y坐标值, 考虑到了滚动条导致的位移差   
  176. */    
  177. pointerY: function(event) {    
  178. return event.pageY || (event.clientY +    
  179. (document.documentElement.scrollTop || document.body.scrollTop));    
  180. },    
  181. /**   
  182. * 停止冒泡(参见 http://www.quirksmode.org/js/events_order.html) 和阻止浏览器执行与事件相关的默认动作   
  183. * 比如   
  184. * <a href="http://www.google.com" onclick="Event.stop(event);">google</a>   
  185. * 那么点击该连接,页面并不会执行转向   
  186. */    
  187. stop: function(event) {    
  188. if (event.preventDefault) {    
  189. event.preventDefault();    
  190. event.stopPropagation();    
  191. else {    
  192. event.returnValue = false;    
  193. }    
  194. },    
  195. // find the first node with the given tagName, starting from the    
  196. // node the event was triggered on; traverses the DOM upwards    
  197. /**   
  198. * 找到事件元素的父级元素中,最接近事件元素且等同于指定标签名的父元素。   
  199. * 如果到达顶级元素(HTML),那么就返回顶级元素   
  200. */    
  201. findElement: function(event, tagName) {    
  202. var element = Event.element(event);    
  203. while (element.parentNode && (!element.tagName ||    
  204. (element.tagName.toUpperCase() != tagName.toUpperCase())))    
  205. element = element.parentNode;    
  206. return element;    
  207. },    
  208. /**   
  209. * 其后的代码封装了事件的注册和反注册,避免ie的内存泄露的bug   
  210. * 参见 http://javascript.weblogsinc.com/en...34000267034921/   
  211. */    
  212. observers: false,    
  213. /**   
  214. * this.observers 的数据格式是一个二维数组,二维的数组分别四个元素分别是   
  215. * [注册事件对象,事件名,事件处理函数,事件处理模式布尔值]   
  216. */    
  217. _observeAndCache: function(element, name, observer, useCapture) {    
  218. if (!this.observers) this.observers = ;    
  219. if (element.addEventListener) {    
  220. this.observers.push([element, name, observer, useCapture]);    
  221. element.addEventListener(name, observer, useCapture);    
  222. else if (element.attachEvent) {    
  223. this.observers.push([element, name, observer, useCapture]);    
  224. element.attachEvent('on' + name, observer);    
  225. }    
  226. },    
  227. unloadCache: function() {    
  228. if (!Event.observers) return;    
  229. for (var i = 0; i < Event.observers.length; i++) {    
  230. /**   
  231. * 这里与 Ajax.Request 对象设置 request header 的代码异曲同工   
  232. */    
  233. Event.stopObserving.apply(this, Event.observers);    
  234. Event.observers[0] = null;    
  235. }    
  236. Event.observers = false;    
  237. },    
  238. /**   
  239. * 注册对象的事件处理,并记录到cache中   
  240. */    
  241. observe: function(element, name, observer, useCapture) {    
  242. var element = $(element);    
  243. useCapture = useCapture || false;    
  244.   
  245. if (name == 'keypress' &&    
  246. ((navigator.appVersion.indexOf('AppleWebKit') > 0)    
  247. || element.attachEvent))    
  248. name = 'keydown';    
  249.   
  250. this._observeAndCache(element, name, observer, useCapture);    
  251. },    
  252. /**   
  253. * 取消对象已注册的事件处理   
  254. */    
  255. stopObserving: function(element, name, observer, useCapture) {    
  256. var element = $(element);    
  257. useCapture = useCapture || false;    
  258.   
  259. if (name == 'keypress' &&    
  260. ((navigator.appVersion.indexOf('AppleWebKit') > 0)    
  261. || element.detachEvent))    
  262. name = 'keydown';    
  263.   
  264. if (element.removeEventListener) {    
  265. element.removeEventListener(name, observer, useCapture);    
  266. else if (element.detachEvent) {    
  267. element.detachEvent('on' + name, observer);    
  268. }    
  269. }    
  270. });    
  271. /* prevent memory leaks in IE */    
  272. /**   
  273. * 页面onload 的时候取消所有事件注册,避免ie内存泄漏的bug   
  274. */    
  275. Event.observe(window, 'unload', Event.unloadCache, false);    
  276. /**   
  277. * Position 对象也是常用的工具类,提供了获取元素在页面上位置的函数,Drag&Drop的效果一定常会用到   
  278. * 具体的应用参考 script.aculo.us 基于prototype 的实现,尤其是dragdrop.js。   
  279. */    
  280. var Position = {    
  281. // set to true if needed, warning: firefox performance problems    
  282. // NOT neeeded for page scrolling, only if draggable contained in    
  283. // scrollable elements    
  284. includeScrollOffsets: false,    
  285. // must be called before calling withinIncludingScrolloffset, every time the    
  286. // page is scrolled    
  287. prepare: function() {    
  288. this.deltaX = window.pageXOffset    
  289. || document.documentElement.scrollLeft    
  290. || document.body.scrollLeft    
  291. || 0;    
  292. this.deltaY = window.pageYOffset    
  293. || document.documentElement.scrollTop    
  294. || document.body.scrollTop    
  295. || 0;    
  296. },    
  297. /**   
  298. * 当对象所处的页面有滚动条是,计算位移   
  299. */    
  300. realOffset: function(element) {    
  301. var valueT = 0, valueL = 0;    
  302. do {    
  303. valueT += element.scrollTop || 0;    
  304. valueL += element.scrollLeft || 0;    
  305. element = element.parentNode;    
  306. while (element);    
  307. return [valueL, valueT];    
  308. },    
  309. /**   
  310. * 计算出对象在页面上的位置   
  311. */    
  312. cumulativeOffset: function(element) {    
  313. var valueT = 0, valueL = 0;    
  314. do {    
  315. valueT += element.offsetTop || 0;    
  316. valueL += element.offsetLeft || 0;    
  317. element = element.offsetParent;    
  318. while (element);    
  319. return [valueL, valueT];    
  320. },    
  321. // caches x/y coordinate pair to use with overlap    
  322. /**   
  323. * 判断一个坐标是否在指定元素的空间范围中   
  324. * 比如你想判断鼠标点击点的坐标是否在某个层或窗口   
  325. */    
  326. within: function(element, x, y) {    
  327. if (this.includeScrollOffsets)    
  328. return this.withinIncludingScrolloffsets(element, x, y);    
  329. this.xcomp = x;    
  330. this.ycomp = y;    
  331. this.offset = this.cumulativeOffset(element);    
  332. return (y >= this.offset[1] &&    
  333. y < this.offset[1] + element.offsetHeight &&    
  334. x >= this.offset[0] &&    
  335. x < this.offset[0] + element.offsetWidth);    
  336. },    
  337. withinIncludingScrolloffsets: function(element, x, y) {    
  338. var offsetcache = this.realOffset(element);    
  339. this.xcomp = x + offsetcache[0] - this.deltaX;    
  340. this.ycomp = y + offsetcache[1] - this.deltaY;    
  341. this.offset = this.cumulativeOffset(element);    
  342. return (this.ycomp >= this.offset[1] &&    
  343. this.ycomp < this.offset[1] + element.offsetHeight &&    
  344. this.xcomp >= this.offset[0] &&    
  345. this.xcomp < this.offset[0] + element.offsetWidth);    
  346. },    
  347. // within must be called directly before    
  348. /**   
  349. * 调用该方法时,确保首先调用了within方法   
  350. * 如果x,y坐标位于element的空间范围中,那么返回一个小于1的标示位置的值,比如0.5标示该坐标位于element空间的中线上   
  351. */    
  352. overlap: function(mode, element) {    
  353. if (!mode) return 0;    
  354. if (mode == 'vertical')    
  355. return ((this.offset[1] + element.offsetHeight) - this.ycomp) /    
  356. element.offsetHeight;    
  357. if (mode == 'horizontal')    
  358. return ((this.offset[0] + element.offsetWidth) - this.xcomp) /    
  359. element.offsetWidth;    
  360. },    
  361. /**   
  362. * 复制源对象的空间数据到目的对象。   
  363. * 常用的地方:拖缀一个层到新地方时,常常动态构造和该层同样大小的虚层。   
  364. */    
  365. clone: function(source, target) {    
  366. source = $(source);    
  367. target = $(target);    
  368. target.style.position = 'absolute';    
  369. var offsets = this.cumulativeOffset(source);    
  370. target.style.top = offsets[1] + 'px';    
  371. target.style.left = offsets[0] + 'px';    
  372. target.style.width = source.offsetWidth + 'px';    
  373. target.style.height = source.offsetHeight + 'px';    
  374. }    
  375. }   
分享到:
评论

相关推荐

    学习protoType的好资料

    在这里,"proto"可能是指协议(Protocol)或者原型(Prototype),而“学习protoType的好资料”则可能是指一个关于网络协议或者JavaScript原型链的学习资源。 首先,如果"protoType"指的是网络协议的实现,那么我们...

    prototype 学习资料

    理解`prototype`是深入学习JavaScript面向对象编程的关键一步。`prototype`主要用于实现对象间的属性和方法共享,是JavaScript实现继承的一种方式。 ### 1. prototype的基本原理 每个JavaScript函数(包括构造函数...

    prototype资料很全

    在JavaScript中,`prototype`是一个非常重要的...理解和掌握`prototype`对于深入学习JavaScript至关重要。通过上述的讲解,你应该对`prototype`有了更全面的理解,也能够更好地运用它来构建和扩展JavaScript的应用。

    Prototype1.5.1使用手册

    《Prototype 1.5.1使用...总结,Prototype 1.5.1使用手册涵盖了该库的主要特性和用法,对于前端开发者来说,是一个不可或缺的学习和参考资料。通过深入学习和实践,可以极大地提升开发效率,创造出更优秀的Web应用。

    jquery+prototype 源码 资料 插件合集

    《jQuery与Prototype:源码解析、资料汇集及插件应用》 在Web开发领域,JavaScript库如jQuery和Prototype因其强大的功能和易用性而备受开发者喜爱。本资源合集包含了这两个库的源码、相关资料以及插件,为开发者...

    prototype-1.6.0.3.js+prototype1.4 、1.5中文手册+prototype1.6英文手册

    总结来说,这个压缩包是学习和使用Prototype JavaScript库的宝贵资源。通过阅读手册,你可以了解如何利用Prototype进行DOM操作、事件处理、Ajax通信和动画效果。而源代码文件`prototype-1.6.0.3.js`则让你可以直接在...

    prototype.js源码及PDF文档

    这份资料对于深入理解Prototype的工作原理和学习JavaScript面向对象编程具有极高的价值。 一、Prototype库简介 Prototype库由Sam Stephenson于2005年创建,它的主要目标是提升JavaScript在浏览器环境下的开发效率,...

    prototype.js框架资料

    压缩包中的“Prototype-v1.6.0.chm”是Prototype.js v1.6.0的离线帮助文档,包含了详细的API介绍和使用示例,是学习和参考的好资源。“prototype-1.6.0.3.js”则是该版本的源码文件,可以直接在项目中使用。而...

    Prototype 中文chm教程 Prototype 中文电子图书 Prototype中文帮助文档下载

    提供的"Prototype.js 中文chm教程"和"Prototype.js 中文电子图书"是学习Prototype.js的宝贵资料,它们涵盖了库的各个方面,从基本用法到高级技巧,帮助开发者快速上手。"Prototype中文帮助文档"则包含了详细的API...

    js学习资料

    李炎恢老师的JS学习资料是一套全面且深入的学习资源,适合初学者和有一定基础的开发者进阶学习。 首先,JavaScript是Web开发的三大核心技术之一,与HTML和CSS共同构建了网页的结构、样式和行为。它的主要应用领域...

    prototype中文帮助文档

    《Prototype.js 中文帮助文档》是为JavaScript开发者提供的一份详尽参考资料,旨在帮助开发者更好地理解和使用Prototype.js库。Prototype.js是一个广泛使用的JavaScript框架,它为JavaScript编程提供了许多实用的...

    Nokia_Prototype_SDK_InstallationGuide下载

    通过本指南的学习,您将了解 Nokia Prototype SDK 的主要功能、系统需求以及安装过程中的关键步骤。 #### 二、系统需求 ##### 2.1 可选预安装要求 在安装 Nokia Prototype SDK 4.0 for Java ME 之前,建议确保满足...

    JS高级学习资料整理(第三月) .docx

    ### JS高级学习资料整理(第三月)知识点梳理 #### 一、函数的创建方式 在JavaScript中,函数可以通过以下三种方式进行创建: 1. **命名函数**:这是最常见的一种方式,可以直接通过`function`关键字来定义一个...

    prototype1.4中文开发者手册

    总的来说,《Prototype 1.4中文开发者手册》是学习和掌握Prototype JavaScript库的必备资料,无论你是初学者还是经验丰富的开发者,都能从中获益匪浅。通过阅读和实践,你将能够编写出更为高效、优雅的JavaScript...

    Prototype API Documentation

    Prototype API 文档是开发者理解和使用Prototype库的重要参考资料。 **一、核心概念** 1. **对象扩展**:Prototype 最为人所知的是它对JavaScript原生对象的扩展,如Array、String、Date等,增加了许多便捷的方法...

    prototype.js1.4版开发者手册

    #### 三、Prototype.js 使用指南 ##### 3.1 $() 方法的使用 - **简介**: `$()` 方法是 `document.getElementById` 的一种便捷替代方案,它能够快速获取 DOM 元素。 - **单个 ID**: 可以通过 `$()` 方法传入一个...

    最新Prototype手册

    《最新Prototype手册》详细解读 ...总结,"最新Prototype手册"是开发者深入理解并掌握Prototype.js的重要参考资料。通过阅读和实践,开发者能够提升JavaScript开发效率,构建更健壮、更高效的Web应用。

    ajax:prototype.js很全的手册

    总的来说,“Ajax: Prototype.js全面手册”是深入理解并有效利用Prototype.js的宝贵资料,无论你是初学者还是经验丰富的开发者,都能从中受益。通过系统学习,你将能够编写出更加高效、简洁的JavaScript代码,提升...

Global site tag (gtag.js) - Google Analytics