Requires

Provides

Element.Position.js

Extends the Element native object to include methods useful positioning elements relative to others.

License:
MIT-style license
Authors:
Aaron Newton
  1. 25
  2. 26
  3. 27
  4. 28
  5. 29
  6. 30
  7. 31
(function(){ var original = Element.prototype.position; Element.implement({ position: function(options){

call original position if the options are x/y values

  1. 33
  2. 34
  3. 35
  4. 36
  5. 37
  6. 38
  7. 39
  8. 40
  9. 41
if (options && (options.x != null || options.y != null)){ return original ? original.apply(this, arguments) : this; } Object.each(options || {}, function(v, k){ if (v == null) delete options[k]; }); options = Object.merge({

minimum: { x: 0, y: 0 }, maximum: { x: 0, y: 0},

  1. 44
  2. 45
  3. 46
  4. 47
  5. 48
  6. 49
  7. 50
  8. 51
  9. 52
  10. 53
  11. 54
  12. 55
  13. 56
relativeTo: document.body, position: { x: 'center', //left, center, right y: 'center' //top, center, bottom }, edge: false, offset: {x: 0, y: 0}, returnPos: false, relFixedPosition: false, ignoreMargins: false, ignoreScroll: false, allowNegative: false }, options);

compute the offset of the parent positioned element if this element is in one

  1. 59
  2. 60
var parentOffset = {x: 0, y: 0}, parentPositioned = false;

dollar around getOffsetParent should not be necessary, but as it does not return * a mootools extended element in IE, an error occurs on the call to expose. See: * http://mootools.lighthouseapp.com/projects/2706/tickets/333-element-getoffsetparent-inconsistency-between-ie-and-other-browsers

  1. 65
  2. 66
  3. 67
  4. 68
  5. 69
  6. 70
  7. 71
  8. 72
  9. 73
  10. 74
  11. 75
var offsetParent = this.measure(function(){ return document.id(this.getOffsetParent()); }); if (offsetParent && offsetParent != this.getDocument().body){ parentOffset = offsetParent.measure(function(){ return this.getPosition(); }); parentPositioned = offsetParent != document.id(options.relativeTo); options.offset.x = options.offset.x - parentOffset.x; options.offset.y = options.offset.y - parentOffset.y; }

upperRight, bottomRight, centerRight, upperLeft, bottomLeft, centerLeft topRight, topLeft, centerTop, centerBottom, center

  1. 79
  2. 80
  3. 81
  4. 82
  5. 83
  6. 84
  7. 85
  8. 86
  9. 87
  10. 88
  11. 89
  12. 90
  13. 91
  14. 92
  15. 93
  16. 94
  17. 95
  18. 96
  19. 97
  20. 98
  21. 99
  22. 100
  23. 101
  24. 102
  25. 103
  26. 104
  27. 105
  28. 106
  29. 107
  30. 108
  31. 109
  32. 110
  33. 111
  34. 112
  35. 113
  36. 114
  37. 115
  38. 116
  39. 117
  40. 118
  41. 119
  42. 120
  43. 121
  44. 122
  45. 123
  46. 124
  47. 125
  48. 126
  49. 127
  50. 128
  51. 129
  52. 130
  53. 131
  54. 132
  55. 133
  56. 134
  57. 135
  58. 136
  59. 137
  60. 138
  61. 139
  62. 140
  63. 141
  64. 142
  65. 143
  66. 144
  67. 145
  68. 146
  69. 147
  70. 148
  71. 149
  72. 150
  73. 151
  74. 152
  75. 153
  76. 154
  77. 155
  78. 156
  79. 157
  80. 158
  81. 159
  82. 160
  83. 161
  84. 162
  85. 163
  86. 164
  87. 165
  88. 166
  89. 167
  90. 168
  91. 169
  92. 170
  93. 171
  94. 172
  95. 173
  96. 174
  97. 175
  98. 176
  99. 177
  100. 178
  101. 179
  102. 180
  103. 181
  104. 182
  105. 183
  106. 184
  107. 185
  108. 186
  109. 187
  110. 188
  111. 189
  112. 190
  113. 191
  114. 192
  115. 193
  116. 194
  117. 195
  118. 196
  119. 197
  120. 198
  121. 199
  122. 200
  123. 201
  124. 202
  125. 203
  126. 204
  127. 205
  128. 206
  129. 207
  130. 208
  131. 209
  132. 210
  133. 211
  134. 212
  135. 213
  136. 214
  137. 215
  138. 216
  139. 217
  140. 218
  141. 219
  142. 220
  143. 221
  144. 222
  145. 223
  146. 224
  147. 225
  148. 226
  149. 227
  150. 228
  151. 229
  152. 230
var fixValue = function(option){ if (typeOf(option) != 'string') return option; option = option.toLowerCase(); var val = {}; if (option.test('left')){ val.x = 'left'; } else if (option.test('right')){ val.x = 'right'; } else { val.x = 'center'; } if (option.test('upper') || option.test('top')){ val.y = 'top'; } else if (option.test('bottom')){ val.y = 'bottom'; } else { val.y = 'center'; } return val; }; options.edge = fixValue(options.edge); options.position = fixValue(options.position); if (!options.edge){ if (options.position.x == 'center' && options.position.y == 'center') options.edge = {x:'center', y:'center'}; else options.edge = {x:'left', y:'top'}; } this.setStyle('position', 'absolute'); var rel = document.id(options.relativeTo) || document.body, calc = rel == document.body ? window.getScroll() : rel.getPosition(), top = calc.y, left = calc.x; var dim = this.getDimensions({ computeSize: true, styles:['padding', 'border','margin'] }); var pos = {}, prefY = options.offset.y, prefX = options.offset.x, winSize = window.getSize(); switch(options.position.x){ case 'left': pos.x = left + prefX; break; case 'right': pos.x = left + prefX + rel.offsetWidth; break; default: //center pos.x = left + ((rel == document.body ? winSize.x : rel.offsetWidth)/2) + prefX; break; } switch(options.position.y){ case 'top': pos.y = top + prefY; break; case 'bottom': pos.y = top + prefY + rel.offsetHeight; break; default: //center pos.y = top + ((rel == document.body ? winSize.y : rel.offsetHeight)/2) + prefY; break; } if (options.edge){ var edgeOffset = {}; switch(options.edge.x){ case 'left': edgeOffset.x = 0; break; case 'right': edgeOffset.x = -dim.x-dim.computedRight-dim.computedLeft; break; default: //center edgeOffset.x = -(dim.totalWidth/2); break; } switch(options.edge.y){ case 'top': edgeOffset.y = 0; break; case 'bottom': edgeOffset.y = -dim.y-dim.computedTop-dim.computedBottom; break; default: //center edgeOffset.y = -(dim.totalHeight/2); break; } pos.x += edgeOffset.x; pos.y += edgeOffset.y; } pos = { left: ((pos.x >= 0 || parentPositioned || options.allowNegative) ? pos.x : 0).toInt(), top: ((pos.y >= 0 || parentPositioned || options.allowNegative) ? pos.y : 0).toInt() }; var xy = {left: 'x', top: 'y'}; ['minimum', 'maximum'].each(function(minmax){ ['left', 'top'].each(function(lr){ var val = options[minmax] ? options[minmax][xy[lr]] : null; if (val != null && pos[lr] < val) pos[lr] = val; }); }); if (rel.getStyle('position') == 'fixed' || options.relFixedPosition){ var winScroll = window.getScroll(); pos.top+= winScroll.y; pos.left+= winScroll.x; } var relScroll = rel.getScroll(); if (options.ignoreScroll){ pos.top -= relScroll.y; pos.left -= relScroll.x; } else { pos.top += relScroll.y; pos.left += relScroll.x; } if (options.ignoreMargins){ pos.left += ( options.edge.x == 'right' ? dim['margin-right'] : options.edge.x == 'center' ? -dim['margin-left'] + ((dim['margin-right'] + dim['margin-left'])/2) : - dim['margin-left'] ); pos.top += ( options.edge.y == 'bottom' ? dim['margin-bottom'] : options.edge.y == 'center' ? -dim['margin-top'] + ((dim['margin-bottom'] + dim['margin-top'])/2) : - dim['margin-top'] ); } pos.left = Math.ceil(pos.left); pos.top = Math.ceil(pos.top); if (options.returnPos) return pos; else this.setStyles(pos); return this; } }); })();