prototype使用学习手册指南之Position.js

来源:互联网 发布:希尔伯特23问题 知乎 编辑:程序博客网 时间:2024/06/02 09:10
 Position是prototype中定义的一个对象,提供了操作DOM中与位置相关的方法,要很好的理解元素在页面中的位置,具体代码如下,按照代码说说,其中英文是作者的注释,中文的才是偶的说明或翻译英文的注释,采用顶式注释法(注释在要说明的代码的上面)说明

  1. // set to true if needed, warning: firefox performance problems 
  2. // NOT neeeded for page scrolling, only if draggable contained in 
  3. // scrollable elements 
  4. //只有在使用拖动的时候元素包含在有滚动条的元素中才需要设置为true 
  5. includeScrollOffsets: false
  6. // must be called before calling withinIncludingScrolloffset, every time the 
  7. // page is scrolled 
  8. //当页面被scrolled后,使用withinIncludingScrolloffset的时候需要先调用这个方法 
  9. prepare: function() { 
  10. //横向滚动条滚动的距离 
  11. this.deltaX = window.pageXOffset 
  12. || document.documentElement.scrollLeft 
  13. || document.body.scrollLeft 
  14. || 0; 
  15. //纵向滚动条滚动的距离 
  16. this.deltaY = window.pageYOffset 
  17. || document.documentElement.scrollTop 
  18. || document.body.scrollTop 
  19. || 0; 
  20. }, 
  21. //元素由于滚动条偏移的总距离 
  22. realOffset: function(element) { 
  23. var valueT = 0, valueL = 0; 
  24. do { 
  25. valueT += element.scrollTop || 0; 
  26. valueL += element.scrollLeft || 0; 
  27. element = element.parentNode; 
  28. while (element); 
  29. return [valueL, valueT]; 
  30. }, 
  31. //元素在页面中由offsetParent累积的offset,当offsetParent都没有滚动条时,就是元素在页面中的位置 
  32. cumulativeOffset: function(element) { 
  33. var valueT = 0, valueL = 0; 
  34. do { 
  35. valueT += element.offsetTop || 0; 
  36. valueL += element.offsetLeft || 0; 
  37. element = element.offsetParent; 
  38. while (element); 
  39. return [valueL, valueT]; 
  40. }, 
  41. //元素相对于containing block("nearest positioned ancestor")的位置,也就是相对于最近的一个position设置为relative或者absolute的祖先节点的位置,如果没有就是相对于 body的位置,跟style.top,style.left一样? 
  42. positionedOffset: function(element) { 
  43. var valueT = 0, valueL = 0; 
  44. do { 
  45. valueT += element.offsetTop || 0; 
  46. valueL += element.offsetLeft || 0; 
  47. element = element.offsetParent; 
  48. if (element) { 
  49. if(element.tagName==’BODY’) break
  50. var p = Element.getStyle(element, 'position’); 
  51. if (p == 'relative’ || p == 'absolute’) break
  52. while (element); 
  53. return [valueL, valueT]; 
  54. }, 
  55. //offsetParent 
  56. offsetParent: function(element) { 
  57. if (element.offsetParent) return element.offsetParent; 
  58. if (element == document.body) return element; 
  59. while ((element = element.parentNode) && element != document.body) 
  60. if (Element.getStyle(element, 'position’) != ’static’) 
  61. return element; 
  62. return document.body; 
  63. }, 
  64. // caches x/y coordinate pair to use with overlap 
  65. //判断指定的位置是否在元素内 
  66. within: function(element, x, y) { 
  67. if (this.includeScrollOffsets) 
  68. return this.withinIncludingScrolloffsets(element, x, y); 
  69. this.xcomp = x; 
  70. this.ycomp = y; 
  71. this.offset = this.cumulativeOffset(element); 
  72. return (y >= this.offset[1] && 
  73. y < this.offset[1] + element.offsetHeight && 
  74. x >= this.offset[0] && 
  75. x < this.offset[0] + element.offsetWidth); 
  76. }, 
  77. //跟within差不多,不过考虑到滚动条,也许是在元素上面,但不是直接在上面,因为滚动条也许已经使元素不可见了 
  78. withinIncludingScrolloffsets: function(element, x, y) { 
  79. var offsetcache = this.realOffset(element); 
  80. this.xcomp = x + offsetcache[0] - this.deltaX; 
  81. this.ycomp = y + offsetcache[1] - this.deltaY; 
  82. this.offset = this.cumulativeOffset(element); 
  83. return (this.ycomp >= this.offset[1] && 
  84. this.ycomp < this.offset[1] + element.offsetHeight && 
  85. this.xcomp >= this.offset[0] && 
  86. this.xcomp < this.offset[0] + element.offsetWidth); 
  87. }, 
  88. // within must be called directly before 
  89. //在调用这个方法前,必须先调用within,返回在with指定的位置在水平或者垂直方向上占用的百分比 
  90. overlap: function(mode, element) { 
  91. if (!mode) return 0; 
  92. if (mode == 'vertical’) 
  93. return ((this.offset[1] + element.offsetHeight) - this.ycomp) / 
  94. element.offsetHeight; 
  95. if (mode == 'horizontal’) 
  96. return ((this.offset[0] + element.offsetWidth) - this.xcomp) / 
  97. element.offsetWidth; 
  98. }, 
  99. //返回元素相对页面的真实位置 
  100. page: function(forElement) { 
  101. var valueT = 0, valueL = 0; 
  102. var element = forElement; 
  103. do { 
  104. valueT += element.offsetTop || 0; 
  105. valueL += element.offsetLeft || 0; 
  106. // Safari fix 
  107. if (element.offsetParent==document.body) 
  108. if (Element.getStyle(element,’position’)==’absolute’) break
  109. while (element = element.offsetParent); 
  110. element = forElement; 
  111. do { 
  112. if (!window.opera || element.tagName==’BODY’) { 
  113. valueT -= element.scrollTop || 0; 
  114. valueL -= element.scrollLeft || 0; 
  115. while (element = element.parentNode); 
  116. return [valueL, valueT]; 
  117. }, 
  118. //设置target为source的位置,大小 
  119. clone: function(source, target) { 
  120. var options = Object.extend({ 
  121. setLeft: true
  122. setTop: true
  123. setWidth: true
  124. setHeight: true
  125. offsetTop: 0, 
  126. offsetLeft: 0 
  127. }, arguments[2] || {}) 
  128. // find page position of source 
  129. source = $(source); 
  130. var p = Position.page(source); 
  131. // find coordinate system to use 
  132. target = $(target); 
  133. var delta = [0, 0]; 
  134. var parent = null
  135. // delta [0,0] will do fine with position: fixed elements, 
  136. // position:absolute needs offsetParent deltas 
  137. if (Element.getStyle(target,’position’) == 'absolute’) { 
  138. parent = Position.offsetParent(target); 
  139. delta = Position.page(parent); 
  140. // correct by body offsets (fixes Safari) 
  141. if (parent == document.body) { 
  142. delta[0] -= document.body.offsetLeft; 
  143. delta[1] -= document.body.offsetTop; 
  144. // set position 
  145. if(options.setLeft) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px’; 
  146. if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px’; 
  147. if(options.setWidth) target.style.width = source.offsetWidth + 'px’; 
  148. if(options.setHeight) target.style.height = source.offsetHeight + 'px’; 
  149. }, 
  150. //将element的position设置为absolute的模式 
  151. absolutize: function(element) { 
  152. element = $(element); 
  153. if (element.style.position == 'absolute’) return
  154. Position.prepare(); 
  155. var offsets = Position.positionedOffset(element); 
  156. var top = offsets[1]; 
  157. var left = offsets[0]; 
  158. var width = element.clientWidth; 
  159. var height = element.clientHeight; 
  160. element._originalLeft = left - parseFloat(element.style.left || 0); 
  161. element._originalTop = top - parseFloat(element.style.top || 0); 
  162. element._originalWidth = element.style.width; 
  163. element._originalHeight = element.style.height; 
  164. element.style.position = 'absolute’; 
  165. element.style.top = top + 'px’;; 
  166. element.style.left = left + 'px’;; 
  167. element.style.width = width + 'px’;; 
  168. element.style.height = height + 'px’;; 
  169. }, 
  170. //将element的position设置为absolute的模式 
  171. relativize: function(element) { 
  172. element = $(element); 
  173. if (element.style.position == 'relative’) return
  174. Position.prepare(); 
  175. element.style.position = 'relative’; 
  176. var top = parseFloat(element.style.top || 0) - (element._originalTop || 0); 
  177. var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0); 
  178. element.style.top = top + 'px’; 
  179. element.style.left = left + 'px’; 
  180. element.style.height = element._originalHeight; 
  181. element.style.width = element._originalWidth; 
  182. // Safari returns margins on body which is incorrect if the child is absolutely 
  183. // positioned. For performance reasons, redefine Position.cumulativeOffset for 
  184. // KHTML/WebKit only. 
  185. if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) { 
  186. Position.cumulativeOffset = function(element) { 
  187. var valueT = 0, valueL = 0; 
  188. do { 
  189. valueT += element.offsetTop || 0; 
  190. valueL += element.offsetLeft || 0; 
  191. if (element.offsetParent == document.body) 
  192. if (Element.getStyle(element, 'position’) == 'absolute’) break
  193. element = element.offsetParent; 
  194. while (element); 
  195. return [valueL, valueT]; 
原创粉丝点击