| 1 | /*! |
|---|
| 2 | * Ext JS Library 3.4.0 |
|---|
| 3 | * Copyright(c) 2006-2011 Sencha Inc. |
|---|
| 4 | * licensing@sencha.com |
|---|
| 5 | * http://www.sencha.com/license |
|---|
| 6 | */ |
|---|
| 7 | /** |
|---|
| 8 | * @class Ext.Element |
|---|
| 9 | */ |
|---|
| 10 | Ext.Element.addMethods({ |
|---|
| 11 | /** |
|---|
| 12 | * Scrolls this element the specified scroll point. It does NOT do bounds checking so if you scroll to a weird value it will try to do it. For auto bounds checking, use scroll(). |
|---|
| 13 | * @param {String} side Either "left" for scrollLeft values or "top" for scrollTop values. |
|---|
| 14 | * @param {Number} value The new scroll value |
|---|
| 15 | * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object |
|---|
| 16 | * @return {Element} this |
|---|
| 17 | */ |
|---|
| 18 | scrollTo : function(side, value, animate) { |
|---|
| 19 | //check if we're scrolling top or left |
|---|
| 20 | var top = /top/i.test(side), |
|---|
| 21 | me = this, |
|---|
| 22 | dom = me.dom, |
|---|
| 23 | prop; |
|---|
| 24 | if (!animate || !me.anim) { |
|---|
| 25 | // just setting the value, so grab the direction |
|---|
| 26 | prop = 'scroll' + (top ? 'Top' : 'Left'); |
|---|
| 27 | dom[prop] = value; |
|---|
| 28 | } |
|---|
| 29 | else { |
|---|
| 30 | // if scrolling top, we need to grab scrollLeft, if left, scrollTop |
|---|
| 31 | prop = 'scroll' + (top ? 'Left' : 'Top'); |
|---|
| 32 | me.anim({scroll: {to: top ? [dom[prop], value] : [value, dom[prop]]}}, me.preanim(arguments, 2), 'scroll'); |
|---|
| 33 | } |
|---|
| 34 | return me; |
|---|
| 35 | }, |
|---|
| 36 | |
|---|
| 37 | /** |
|---|
| 38 | * Scrolls this element into view within the passed container. |
|---|
| 39 | * @param {Mixed} container (optional) The container element to scroll (defaults to document.body). Should be a |
|---|
| 40 | * string (id), dom node, or Ext.Element. |
|---|
| 41 | * @param {Boolean} hscroll (optional) False to disable horizontal scroll (defaults to true) |
|---|
| 42 | * @return {Ext.Element} this |
|---|
| 43 | */ |
|---|
| 44 | scrollIntoView : function(container, hscroll) { |
|---|
| 45 | var c = Ext.getDom(container) || Ext.getBody().dom, |
|---|
| 46 | el = this.dom, |
|---|
| 47 | o = this.getOffsetsTo(c), |
|---|
| 48 | l = o[0] + c.scrollLeft, |
|---|
| 49 | t = o[1] + c.scrollTop, |
|---|
| 50 | b = t + el.offsetHeight, |
|---|
| 51 | r = l + el.offsetWidth, |
|---|
| 52 | ch = c.clientHeight, |
|---|
| 53 | ct = parseInt(c.scrollTop, 10), |
|---|
| 54 | cl = parseInt(c.scrollLeft, 10), |
|---|
| 55 | cb = ct + ch, |
|---|
| 56 | cr = cl + c.clientWidth; |
|---|
| 57 | |
|---|
| 58 | if (el.offsetHeight > ch || t < ct) { |
|---|
| 59 | c.scrollTop = t; |
|---|
| 60 | } |
|---|
| 61 | else if (b > cb) { |
|---|
| 62 | c.scrollTop = b-ch; |
|---|
| 63 | } |
|---|
| 64 | // corrects IE, other browsers will ignore |
|---|
| 65 | c.scrollTop = c.scrollTop; |
|---|
| 66 | |
|---|
| 67 | if (hscroll !== false) { |
|---|
| 68 | if (el.offsetWidth > c.clientWidth || l < cl) { |
|---|
| 69 | c.scrollLeft = l; |
|---|
| 70 | } |
|---|
| 71 | else if (r > cr) { |
|---|
| 72 | c.scrollLeft = r - c.clientWidth; |
|---|
| 73 | } |
|---|
| 74 | c.scrollLeft = c.scrollLeft; |
|---|
| 75 | } |
|---|
| 76 | return this; |
|---|
| 77 | }, |
|---|
| 78 | |
|---|
| 79 | // private |
|---|
| 80 | scrollChildIntoView : function(child, hscroll) { |
|---|
| 81 | Ext.fly(child, '_scrollChildIntoView').scrollIntoView(this, hscroll); |
|---|
| 82 | }, |
|---|
| 83 | |
|---|
| 84 | /** |
|---|
| 85 | * Scrolls this element the specified direction. Does bounds checking to make sure the scroll is |
|---|
| 86 | * within this element's scrollable range. |
|---|
| 87 | * @param {String} direction Possible values are: "l" (or "left"), "r" (or "right"), "t" (or "top", or "up"), "b" (or "bottom", or "down"). |
|---|
| 88 | * @param {Number} distance How far to scroll the element in pixels |
|---|
| 89 | * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object |
|---|
| 90 | * @return {Boolean} Returns true if a scroll was triggered or false if the element |
|---|
| 91 | * was scrolled as far as it could go. |
|---|
| 92 | */ |
|---|
| 93 | scroll : function(direction, distance, animate) { |
|---|
| 94 | if (!this.isScrollable()) { |
|---|
| 95 | return false; |
|---|
| 96 | } |
|---|
| 97 | var el = this.dom, |
|---|
| 98 | l = el.scrollLeft, t = el.scrollTop, |
|---|
| 99 | w = el.scrollWidth, h = el.scrollHeight, |
|---|
| 100 | cw = el.clientWidth, ch = el.clientHeight, |
|---|
| 101 | scrolled = false, v, |
|---|
| 102 | hash = { |
|---|
| 103 | l: Math.min(l + distance, w-cw), |
|---|
| 104 | r: v = Math.max(l - distance, 0), |
|---|
| 105 | t: Math.max(t - distance, 0), |
|---|
| 106 | b: Math.min(t + distance, h-ch) |
|---|
| 107 | }; |
|---|
| 108 | hash.d = hash.b; |
|---|
| 109 | hash.u = hash.t; |
|---|
| 110 | |
|---|
| 111 | direction = direction.substr(0, 1); |
|---|
| 112 | if ((v = hash[direction]) > -1) { |
|---|
| 113 | scrolled = true; |
|---|
| 114 | this.scrollTo(direction == 'l' || direction == 'r' ? 'left' : 'top', v, this.preanim(arguments, 2)); |
|---|
| 115 | } |
|---|
| 116 | return scrolled; |
|---|
| 117 | } |
|---|
| 118 | }); |
|---|