Element.position.html 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5. <title>The source code</title>
  6. <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
  7. <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
  8. <style type="text/css">
  9. .highlight { display: block; background-color: #ddd; }
  10. </style>
  11. <script type="text/javascript">
  12. function highlight() {
  13. document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
  14. }
  15. </script>
  16. </head>
  17. <body onload="prettyPrint(); highlight();">
  18. <pre class="prettyprint lang-js"><span id='Ext-dom-Element'>/**
  19. </span> * @class Ext.dom.Element
  20. */
  21. (function() {
  22. var Element = Ext.dom.Element,
  23. LEFT = &quot;left&quot;,
  24. RIGHT = &quot;right&quot;,
  25. TOP = &quot;top&quot;,
  26. BOTTOM = &quot;bottom&quot;,
  27. POSITION = &quot;position&quot;,
  28. STATIC = &quot;static&quot;,
  29. RELATIVE = &quot;relative&quot;,
  30. AUTO = &quot;auto&quot;,
  31. ZINDEX = &quot;z-index&quot;,
  32. BODY = 'BODY',
  33. PADDING = 'padding',
  34. BORDER = 'border',
  35. SLEFT = '-left',
  36. SRIGHT = '-right',
  37. STOP = '-top',
  38. SBOTTOM = '-bottom',
  39. SWIDTH = '-width',
  40. // special markup used throughout Ext when box wrapping elements
  41. borders = {l: BORDER + SLEFT + SWIDTH, r: BORDER + SRIGHT + SWIDTH, t: BORDER + STOP + SWIDTH, b: BORDER + SBOTTOM + SWIDTH},
  42. paddings = {l: PADDING + SLEFT, r: PADDING + SRIGHT, t: PADDING + STOP, b: PADDING + SBOTTOM},
  43. paddingsTLRB = [paddings.l, paddings.r, paddings.t, paddings.b],
  44. bordersTLRB = [borders.l, borders.r, borders.t, borders.b],
  45. positionTopLeft = ['position', 'top', 'left'];
  46. Element.override({
  47. getX: function() {
  48. return Element.getX(this.dom);
  49. },
  50. getY: function() {
  51. return Element.getY(this.dom);
  52. },
  53. <span id='Ext-dom-Element-method-getXY'> /**
  54. </span> * Gets the current position of the element based on page coordinates.
  55. * Element must be part of the DOM tree to have page coordinates
  56. * (display:none or elements not appended return false).
  57. * @return {Number[]} The XY position of the element
  58. */
  59. getXY: function() {
  60. return Element.getXY(this.dom);
  61. },
  62. <span id='Ext-dom-Element-method-getOffsetsTo'> /**
  63. </span> * Returns the offsets of this element from the passed element. Both element must be part
  64. * of the DOM tree and not have display:none to have page coordinates.
  65. * @param {String/HTMLElement/Ext.Element} element The element to get the offsets from.
  66. * @return {Number[]} The XY page offsets (e.g. `[100, -200]`)
  67. */
  68. getOffsetsTo : function(el){
  69. var o = this.getXY(),
  70. e = Ext.fly(el, '_internal').getXY();
  71. return [o[0] - e[0],o[1] - e[1]];
  72. },
  73. setX: function(x, animate) {
  74. return this.setXY([x, this.getY()], animate);
  75. },
  76. setY: function(y, animate) {
  77. return this.setXY([this.getX(), y], animate);
  78. },
  79. setLeft: function(left) {
  80. this.setStyle(LEFT, this.addUnits(left));
  81. return this;
  82. },
  83. setTop: function(top) {
  84. this.setStyle(TOP, this.addUnits(top));
  85. return this;
  86. },
  87. setRight: function(right) {
  88. this.setStyle(RIGHT, this.addUnits(right));
  89. return this;
  90. },
  91. setBottom: function(bottom) {
  92. this.setStyle(BOTTOM, this.addUnits(bottom));
  93. return this;
  94. },
  95. <span id='Ext-dom-Element-method-setXY'> /**
  96. </span> * Sets the position of the element in page coordinates, regardless of how the element
  97. * is positioned. The element must be part of the DOM tree to have page coordinates
  98. * (`display:none` or elements not appended return false).
  99. * @param {Number[]} pos Contains X &amp; Y [x, y] values for new position (coordinates are page-based)
  100. * @param {Boolean/Object} [animate] True for the default animation, or a standard Element
  101. * animation config object
  102. * @return {Ext.Element} this
  103. */
  104. setXY: function(pos, animate) {
  105. var me = this;
  106. if (!animate || !me.anim) {
  107. Element.setXY(me.dom, pos);
  108. }
  109. else {
  110. if (!Ext.isObject(animate)) {
  111. animate = {};
  112. }
  113. me.animate(Ext.applyIf({ to: { x: pos[0], y: pos[1] } }, animate));
  114. }
  115. return me;
  116. },
  117. pxRe: /^\d+(?:\.\d*)?px$/i,
  118. <span id='Ext-dom-Element-method-getLocalX'> /**
  119. </span> * Returns the x-coordinate of this element reletive to its `offsetParent`.
  120. * @return {Number} The local x-coordinate (relative to the `offsetParent`).
  121. */
  122. getLocalX: function() {
  123. var me = this,
  124. offsetParent,
  125. x = me.getStyle(LEFT);
  126. if (!x || x === AUTO) {
  127. return 0;
  128. }
  129. if (x &amp;&amp; me.pxRe.test(x)) {
  130. return parseFloat(x);
  131. }
  132. x = me.getX();
  133. offsetParent = me.dom.offsetParent;
  134. if (offsetParent) {
  135. x -= Ext.fly(offsetParent).getX();
  136. }
  137. return x;
  138. },
  139. <span id='Ext-dom-Element-method-getLocalY'> /**
  140. </span> * Returns the y-coordinate of this element reletive to its `offsetParent`.
  141. * @return {Number} The local y-coordinate (relative to the `offsetParent`).
  142. */
  143. getLocalY: function() {
  144. var me = this,
  145. offsetParent,
  146. y = me.getStyle(TOP);
  147. if (!y || y === AUTO) {
  148. return 0;
  149. }
  150. if (y &amp;&amp; me.pxRe.test(y)) {
  151. return parseFloat(y);
  152. }
  153. y = me.getY();
  154. offsetParent = me.dom.offsetParent;
  155. if (offsetParent) {
  156. y -= Ext.fly(offsetParent).getY();
  157. }
  158. return y;
  159. },
  160. getLeft: function(local) {
  161. return local ? this.getLocalX() : this.getX();
  162. },
  163. getRight: function(local) {
  164. return (local ? this.getLocalX() : this.getX()) + this.getWidth();
  165. },
  166. getTop: function(local) {
  167. return local ? this.getLocalY() : this.getY();
  168. },
  169. getBottom: function(local) {
  170. return (local ? this.getLocalY() : this.getY()) + this.getHeight();
  171. },
  172. translatePoints: function(x, y) {
  173. var me = this,
  174. styles = me.getStyle(positionTopLeft),
  175. relative = styles.position == 'relative',
  176. left = parseFloat(styles.left),
  177. top = parseFloat(styles.top),
  178. xy = me.getXY();
  179. if (Ext.isArray(x)) {
  180. y = x[1];
  181. x = x[0];
  182. }
  183. if (isNaN(left)) {
  184. left = relative ? 0 : me.dom.offsetLeft;
  185. }
  186. if (isNaN(top)) {
  187. top = relative ? 0 : me.dom.offsetTop;
  188. }
  189. left = (typeof x == 'number') ? x - xy[0] + left : undefined;
  190. top = (typeof y == 'number') ? y - xy[1] + top : undefined;
  191. return {
  192. left: left,
  193. top: top
  194. };
  195. },
  196. setBox: function(box, adjust, animate) {
  197. var me = this,
  198. w = box.width,
  199. h = box.height;
  200. if ((adjust &amp;&amp; !me.autoBoxAdjust) &amp;&amp; !me.isBorderBox()) {
  201. w -= (me.getBorderWidth(&quot;lr&quot;) + me.getPadding(&quot;lr&quot;));
  202. h -= (me.getBorderWidth(&quot;tb&quot;) + me.getPadding(&quot;tb&quot;));
  203. }
  204. me.setBounds(box.x, box.y, w, h, animate);
  205. return me;
  206. },
  207. getBox: function(contentBox, local) {
  208. var me = this,
  209. xy,
  210. left,
  211. top,
  212. paddingWidth,
  213. bordersWidth,
  214. l, r, t, b, w, h, bx;
  215. if (!local) {
  216. xy = me.getXY();
  217. } else {
  218. xy = me.getStyle([LEFT, TOP]);
  219. xy = [ parseFloat(xy.left) || 0, parseFloat(xy.top) || 0];
  220. }
  221. w = me.getWidth();
  222. h = me.getHeight();
  223. if (!contentBox) {
  224. bx = {
  225. x: xy[0],
  226. y: xy[1],
  227. 0: xy[0],
  228. 1: xy[1],
  229. width: w,
  230. height: h
  231. };
  232. } else {
  233. paddingWidth = me.getStyle(paddingsTLRB);
  234. bordersWidth = me.getStyle(bordersTLRB);
  235. l = (parseFloat(bordersWidth[borders.l]) || 0) + (parseFloat(paddingWidth[paddings.l]) || 0);
  236. r = (parseFloat(bordersWidth[borders.r]) || 0) + (parseFloat(paddingWidth[paddings.r]) || 0);
  237. t = (parseFloat(bordersWidth[borders.t]) || 0) + (parseFloat(paddingWidth[paddings.t]) || 0);
  238. b = (parseFloat(bordersWidth[borders.b]) || 0) + (parseFloat(paddingWidth[paddings.b]) || 0);
  239. bx = {
  240. x: xy[0] + l,
  241. y: xy[1] + t,
  242. 0: xy[0] + l,
  243. 1: xy[1] + t,
  244. width: w - (l + r),
  245. height: h - (t + b)
  246. };
  247. }
  248. bx.right = bx.x + bx.width;
  249. bx.bottom = bx.y + bx.height;
  250. return bx;
  251. },
  252. getPageBox: function(getRegion) {
  253. var me = this,
  254. el = me.dom,
  255. isDoc = el.nodeName == BODY,
  256. w = isDoc ? Ext.dom.AbstractElement.getViewWidth() : el.offsetWidth,
  257. h = isDoc ? Ext.dom.AbstractElement.getViewHeight() : el.offsetHeight,
  258. xy = me.getXY(),
  259. t = xy[1],
  260. r = xy[0] + w,
  261. b = xy[1] + h,
  262. l = xy[0];
  263. if (getRegion) {
  264. return new Ext.util.Region(t, r, b, l);
  265. }
  266. else {
  267. return {
  268. left: l,
  269. top: t,
  270. width: w,
  271. height: h,
  272. right: r,
  273. bottom: b
  274. };
  275. }
  276. },
  277. <span id='Ext-dom-Element-method-setLocation'> /**
  278. </span> * Sets the position of the element in page coordinates, regardless of how the element
  279. * is positioned. The element must be part of the DOM tree to have page coordinates
  280. * (`display:none` or elements not appended return false).
  281. * @param {Number} x X value for new position (coordinates are page-based)
  282. * @param {Number} y Y value for new position (coordinates are page-based)
  283. * @param {Boolean/Object} [animate] True for the default animation, or a standard Element
  284. * animation config object
  285. * @return {Ext.dom.AbstractElement} this
  286. */
  287. setLocation : function(x, y, animate) {
  288. return this.setXY([x, y], animate);
  289. },
  290. <span id='Ext-dom-Element-method-moveTo'> /**
  291. </span> * Sets the position of the element in page coordinates, regardless of how the element
  292. * is positioned. The element must be part of the DOM tree to have page coordinates
  293. * (`display:none` or elements not appended return false).
  294. * @param {Number} x X value for new position (coordinates are page-based)
  295. * @param {Number} y Y value for new position (coordinates are page-based)
  296. * @param {Boolean/Object} [animate] True for the default animation, or a standard Element
  297. * animation config object
  298. * @return {Ext.dom.AbstractElement} this
  299. */
  300. moveTo : function(x, y, animate) {
  301. return this.setXY([x, y], animate);
  302. },
  303. <span id='Ext-dom-Element-method-position'> /**
  304. </span> * Initializes positioning on this element. If a desired position is not passed, it will make the
  305. * the element positioned relative IF it is not already positioned.
  306. * @param {String} [pos] Positioning to use &quot;relative&quot;, &quot;absolute&quot; or &quot;fixed&quot;
  307. * @param {Number} [zIndex] The zIndex to apply
  308. * @param {Number} [x] Set the page X position
  309. * @param {Number} [y] Set the page Y position
  310. */
  311. position : function(pos, zIndex, x, y) {
  312. var me = this;
  313. if (!pos &amp;&amp; me.isStyle(POSITION, STATIC)) {
  314. me.setStyle(POSITION, RELATIVE);
  315. } else if (pos) {
  316. me.setStyle(POSITION, pos);
  317. }
  318. if (zIndex) {
  319. me.setStyle(ZINDEX, zIndex);
  320. }
  321. if (x || y) {
  322. me.setXY([x || false, y || false]);
  323. }
  324. },
  325. <span id='Ext-dom-Element-method-clearPositioning'> /**
  326. </span> * Clears positioning back to the default when the document was loaded.
  327. * @param {String} [value=''] The value to use for the left, right, top, bottom. You could use 'auto'.
  328. * @return {Ext.dom.AbstractElement} this
  329. */
  330. clearPositioning : function(value) {
  331. value = value || '';
  332. this.setStyle({
  333. left : value,
  334. right : value,
  335. top : value,
  336. bottom : value,
  337. &quot;z-index&quot; : &quot;&quot;,
  338. position : STATIC
  339. });
  340. return this;
  341. },
  342. <span id='Ext-dom-Element-method-getPositioning'> /**
  343. </span> * Gets an object with all CSS positioning properties. Useful along with #setPostioning to get
  344. * snapshot before performing an update and then restoring the element.
  345. * @return {Object}
  346. */
  347. getPositioning : function(){
  348. var styles = this.getStyle([LEFT, TOP, POSITION, RIGHT, BOTTOM, ZINDEX]);
  349. styles[RIGHT] = styles[LEFT] ? '' : styles[RIGHT];
  350. styles[BOTTOM] = styles[TOP] ? '' : styles[BOTTOM];
  351. return styles;
  352. },
  353. <span id='Ext-dom-Element-method-setPositioning'> /**
  354. </span> * Set positioning with an object returned by #getPositioning.
  355. * @param {Object} posCfg
  356. * @return {Ext.dom.AbstractElement} this
  357. */
  358. setPositioning : function(pc) {
  359. var me = this,
  360. style = me.dom.style;
  361. me.setStyle(pc);
  362. if (pc.right == AUTO) {
  363. style.right = &quot;&quot;;
  364. }
  365. if (pc.bottom == AUTO) {
  366. style.bottom = &quot;&quot;;
  367. }
  368. return me;
  369. },
  370. <span id='Ext-dom-Element-method-move'> /**
  371. </span> * Move this element relative to its current position.
  372. * @param {String} direction Possible values are:
  373. *
  374. * - `&quot;l&quot;` (or `&quot;left&quot;`)
  375. * - `&quot;r&quot;` (or `&quot;right&quot;`)
  376. * - `&quot;t&quot;` (or `&quot;top&quot;`, or `&quot;up&quot;`)
  377. * - `&quot;b&quot;` (or `&quot;bottom&quot;`, or `&quot;down&quot;`)
  378. *
  379. * @param {Number} distance How far to move the element in pixels
  380. * @param {Boolean/Object} [animate] true for the default animation or a standard Element
  381. * animation config object
  382. */
  383. move: function(direction, distance, animate) {
  384. var me = this,
  385. xy = me.getXY(),
  386. x = xy[0],
  387. y = xy[1],
  388. left = [x - distance, y],
  389. right = [x + distance, y],
  390. top = [x, y - distance],
  391. bottom = [x, y + distance],
  392. hash = {
  393. l: left,
  394. left: left,
  395. r: right,
  396. right: right,
  397. t: top,
  398. top: top,
  399. up: top,
  400. b: bottom,
  401. bottom: bottom,
  402. down: bottom
  403. };
  404. direction = direction.toLowerCase();
  405. me.moveTo(hash[direction][0], hash[direction][1], animate);
  406. },
  407. <span id='Ext-dom-Element-method-setLeftTop'> /**
  408. </span> * Conveniently sets left and top adding default units.
  409. * @param {String} left The left CSS property value
  410. * @param {String} top The top CSS property value
  411. * @return {Ext.dom.Element} this
  412. */
  413. setLeftTop: function(left, top) {
  414. var style = this.dom.style;
  415. style.left = Element.addUnits(left);
  416. style.top = Element.addUnits(top);
  417. return this;
  418. },
  419. <span id='Ext-dom-Element-method-getRegion'> /**
  420. </span> * Returns the region of this element.
  421. * The element must be part of the DOM tree to have a region
  422. * (display:none or elements not appended return false).
  423. * @return {Ext.util.Region} A Region containing &quot;top, left, bottom, right&quot; member data.
  424. */
  425. getRegion: function() {
  426. return this.getPageBox(true);
  427. },
  428. <span id='Ext-dom-Element-method-getViewRegion'> /**
  429. </span> * Returns the **content** region of this element. That is the region within the borders and padding.
  430. * @return {Ext.util.Region} A Region containing &quot;top, left, bottom, right&quot; member data.
  431. */
  432. getViewRegion: function() {
  433. var me = this,
  434. isBody = me.dom.nodeName == BODY,
  435. scroll, pos, top, left, width, height;
  436. // For the body we want to do some special logic
  437. if (isBody) {
  438. scroll = me.getScroll();
  439. left = scroll.left;
  440. top = scroll.top;
  441. width = Ext.dom.AbstractElement.getViewportWidth();
  442. height = Ext.dom.AbstractElement.getViewportHeight();
  443. }
  444. else {
  445. pos = me.getXY();
  446. left = pos[0] + me.getBorderWidth('l') + me.getPadding('l');
  447. top = pos[1] + me.getBorderWidth('t') + me.getPadding('t');
  448. width = me.getWidth(true);
  449. height = me.getHeight(true);
  450. }
  451. return new Ext.util.Region(top, left + width - 1, top + height - 1, left);
  452. },
  453. <span id='Ext-dom-Element-method-setBounds'> /**
  454. </span> * Sets the element's position and size in one shot. If animation is true then width, height,
  455. * x and y will be animated concurrently.
  456. *
  457. * @param {Number} x X value for new position (coordinates are page-based)
  458. * @param {Number} y Y value for new position (coordinates are page-based)
  459. * @param {Number/String} width The new width. This may be one of:
  460. *
  461. * - A Number specifying the new width in this Element's {@link #defaultUnit}s (by default, pixels)
  462. * - A String used to set the CSS width style. Animation may **not** be used.
  463. *
  464. * @param {Number/String} height The new height. This may be one of:
  465. *
  466. * - A Number specifying the new height in this Element's {@link #defaultUnit}s (by default, pixels)
  467. * - A String used to set the CSS height style. Animation may **not** be used.
  468. *
  469. * @param {Boolean/Object} [animate] true for the default animation or a standard Element
  470. * animation config object
  471. *
  472. * @return {Ext.dom.AbstractElement} this
  473. */
  474. setBounds: function(x, y, width, height, animate) {
  475. var me = this;
  476. if (!animate || !me.anim) {
  477. me.setSize(width, height);
  478. me.setLocation(x, y);
  479. } else {
  480. if (!Ext.isObject(animate)) {
  481. animate = {};
  482. }
  483. me.animate(Ext.applyIf({
  484. to: {
  485. x: x,
  486. y: y,
  487. width: me.adjustWidth(width),
  488. height: me.adjustHeight(height)
  489. }
  490. }, animate));
  491. }
  492. return me;
  493. },
  494. <span id='Ext-dom-Element-method-setRegion'> /**
  495. </span> * Sets the element's position and size the specified region. If animation is true then width, height,
  496. * x and y will be animated concurrently.
  497. *
  498. * @param {Ext.util.Region} region The region to fill
  499. * @param {Boolean/Object} [animate] true for the default animation or a standard Element
  500. * animation config object
  501. * @return {Ext.dom.AbstractElement} this
  502. */
  503. setRegion: function(region, animate) {
  504. return this.setBounds(region.left, region.top, region.right - region.left, region.bottom - region.top, animate);
  505. }
  506. });
  507. }());
  508. </pre>
  509. </body>
  510. </html>