我思故我強

          prototype學習資料(三)


          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. *?google? ?
          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. } ??

          posted on 2007-09-20 19:40 李云澤 閱讀(275) 評論(0)  編輯  收藏 所屬分類: Prototype(Ajax)

          主站蜘蛛池模板: 鹿泉市| 城步| 安丘市| 昌平区| 柳河县| 墨竹工卡县| 侯马市| 荣成市| 西宁市| 柞水县| 吴旗县| 同心县| 轮台县| 且末县| 福贡县| 会东县| 惠州市| 平远县| 诏安县| 桃园县| 南川市| 灌云县| 邯郸县| 南丹县| 长沙市| 彩票| 揭西县| 万荣县| 石首市| 家居| 米易县| 西乡县| 嵊州市| 丰都县| 沧源| 南宫市| 邯郸市| 科技| 铜山县| 海伦市| 河曲县|