/** @name Edo.controls.ScrollBar @class @typeName ScrollBar @description 横向滚动条 @extend Edo.controls.Slider */ Edo.controls.ScrollBar = function(){ Edo.controls.ScrollBar.superclass.constructor.call(this); /** @name Edo.controls.ScrollBar#scrollstart @event @description 滚动条拖拽开始 @property {String} direction 滚动方向(vertical/horizontal) @property {Number} value 滚动条当前值 */ /** @name Edo.controls.ScrollBar#scroll @event @description 滚动条拖拽中 @property {String} direction 滚动方向(vertical/horizontal) @property {Number} value 滚动条当前值 */ /** @name Edo.controls.ScrollBar#scrollcomplete @event @description 滚动条拖拽完成 @property {String} direction 滚动方向(vertical/horizontal) @property {Number} value 滚动条当前值 */ }; Edo.controls.ScrollBar.extend(Edo.controls.Control,{ /** @name Edo.controls.ScrollBar#valueField @property @default value */ valueField: 'value', /** @name Edo.controls.ScrollBar#defaultValue @property @type Number @default 0 */ defaultValue: 0, /** @name Edo.controls.ScrollBar#minWidth @property @default 17 */ minWidth: 17, /** @name Edo.controls.ScrollBar#minHeight @property @default 17 */ minHeight: 17, /** @name Edo.controls.ScrollBar#defaultWidth @property @default 100 */ defaultWidth: 100, /** @name Edo.controls.ScrollBar#defaultHeight @property @default 17 */ defaultHeight: 17, upWidth: 17, upHeight: 17, downWidth: 17, downHeight: 17, /** @name Edo.controls.ScrollBar#maxValue @property @type Number @default 0 @description 最大值 */ maxValue: 0, /** @name Edo.controls.ScrollBar#value @property @type Number @default 0 @description 值 */ value: 0, minHandleSize: 7, //up/down的增量 /** @name Edo.controls.ScrollBar#incrementValue @property @type Number @default 10 @description 箭头点击的增量值 */ incrementValue: 10, /** @name Edo.controls.ScrollBar#alternateIncrementValue @property @type Number @default 10 @description 点击滚动条的增量值 */ alternateIncrementValue: 30, spinTime: 20, scrollTime: 70, /** @name Edo.controls.ScrollBar#direction @property @type horizontal, vertical @default horizontal @description 横竖方位 */ direction: 'horizontal', //horizontal elCls: 'e-div e-scrollbar', upPressedCls: 'e-scrollbar-up-pressed', downPressedCls: 'e-scrollbar-down-pressed', handlePressedCls: 'e-scrollbar-handle-pressed', set: function(o, value){ if(!o) return; if(typeof o == 'string') { var _ = o; o = {}; o[_] = value; } if(o.maxValue){ this._setMaxValue(o.maxValue); delete o.maxValue; } if(o.maxValue){ this._setMaxValue(o.maxValue); delete o.maxValue; } Edo.controls.ScrollBar.superclass.set.c(this, o); }, getInnerHtml: function(sb){ if(this.direction == 'horizontal'){ this.elCls += ' e-hscrollbar'; } sb[sb.length] = '
'; }, createChildren: function(el){ Edo.controls.ScrollBar.superclass.createChildren.call(this, el); this.handle = this.el.firstChild; this.upBtn = this.el.childNodes[1]; this.downBtn = this.el.lastChild; }, initEvents: function(){ if(!this.design){ this.on('mousedown', this._onMousedown, this); Edo.util.Dom.addClassOnClick(this.upBtn, this.upPressedCls); Edo.util.Dom.addClassOnClick(this.downBtn, this.downPressedCls); Edo.util.Dom.addClassOnClick(this.handle, this.handlePressedCls); Edo.util.Dom.addClassOnClick(this.el, '', this._stopSpin.bind(this)); } Edo.controls.ScrollBar.superclass.initEvents.call(this); }, syncSize: function(){ Edo.controls.ScrollBar.superclass.syncSize.call(this); var handleSize = this.getHandleSize(); if(this.direction == 'vertical'){ Edo.util.Dom.setHeight(this.handle, handleSize); }else{ Edo.util.Dom.setWidth(this.handle, handleSize); } this.syncScroll(); }, //获得handle的尺寸 getHandleSize: function(){ var size = 0; var btnSize, //滚动条按钮尺寸 size, //滚动条尺寸 max, //滚动条最大尺寸 handleSize; //handle尺寸 if(this.direction == 'vertical'){ btnSize = this.upHeight + this.downHeight; size = this.realHeight; max = this.maxValue; }else{ btnSize = this.upWidth + this.downWidth; size = this.realWidth; max = this.maxValue; } if(size == max + size){ handleSize = 0; }else{ handleSize = Math.max(this.minHandleSize, Math.round( (size - btnSize) * size / (max+size)) ) } return handleSize; }, //获得handle的偏移定位 getHandleOffset: function(handleSize){ var btnSize, //滚动条按钮尺寸 size, //滚动条尺寸 max, //滚动条最大尺寸 realOffset if(this.direction == 'vertical'){ btnSize = this.upHeight + this.downHeight; size = this.realHeight; max = this.maxValue; realOffset = this.value; }else{ btnSize = this.upWidth + this.downWidth; size = this.realWidth; max = this.maxValue; realOffset = this.value; } //获得 size - btnSize - handleSize的尺寸 var moveSize = size - btnSize - handleSize; //这个就是可移动的范围 offset = realOffset/max*moveSize; return offset; }, createvalue: function(offset, moveSize){ var value = offset * this.maxValue / moveSize return Math.floor(value); }, createvalue: function(offset, moveSize){ var value = offset * this.maxValue / moveSize return Math.floor(value); }, //获得可移动的区域 getMoveReginBox: function(){ var box = this.getBox(); var size = this.getHandleSize(); if(this.direction == 'vertical'){ box.y += this.upHeight; box.height -= (this.upHeight + this.downHeight + size); }else{ box.x += this.upWidth; box.width -= (this.upWidth + this.downWidth + size); } box.right = box.x + box.width; box.bottom = box.y + box.height; return box; }, _onMousedown: function(e){ if(e.button != 0) return false; var t = e.target; var isVertical = this.direction == 'vertical'; this._stopSpin(); if(Edo.util.Dom.contains(this.handle, t)){ Edo.managers.DragManager.startDrag({ event: e, capture: true, dragObject: this.handle, delay: 30, alpha: 1, enableDrop: false, ondragstart: this._onHandleDragStart.bind(this), ondragmove: this._onHandleDragMove.bind(this), ondragcomplete: this._onHandleDragComplete.bind(this) }); }else if(Edo.util.Dom.contains(this.upBtn, t)){ //up this._startSpin('up', this.incrementValue, this.spinTime); this.canFireComplete = true; }else if(Edo.util.Dom.contains(this.downBtn, t)){ //down this._startSpin('down', this.incrementValue, this.spinTime); this.canFireComplete = true; }else{ var moveBox = this.getMoveReginBox(); var handleSie = this.getHandleSize(); if(isVertical) moveBox.height += this.downHeight + handleSie; else moveBox.width += this.downWidth + handleSie; var moveBox2 = this.getMoveReginBox(); var handleXY = Edo.util.Dom.getXY(this.handle); if(Edo.util.Dom.isInRegin(e.xy, moveBox)){ if(isVertical){ this.stopOffset = this.createvalue(Math.abs(moveBox2.y - e.xy[1]), moveBox2.height); if(e.xy[1] < handleXY[1]){ this._startSpin('up', this.alternateIncrementValue, this.spinTime); }else{ this._startSpin('down', this.alternateIncrementValue, this.spinTime); } }else{ this.stopOffset = this.createvalue(Math.abs(moveBox2.x - e.xy[0]), moveBox2.width); if(e.xy[0] < handleXY[0]){ this._startSpin('up', this.alternateIncrementValue, this.spinTime); }else{ this._startSpin('down', this.alternateIncrementValue, this.spinTime); } } } //alert(this.stopOffset); this.canFireComplete = true; } }, doSpin: function(spinDirection, increment){ var isVertical = this.direction == 'vertical'; if(spinDirection == 'up'){ if(isVertical){ var v = this.value - increment; if(Edo.isValue(this.stopOffset) && v < this.stopOffset){ return; } this._setValue(v); }else{ var v = this.value - increment; if(Edo.isValue(this.stopOffset) && v < this.stopOffset){ return; } this._setValue(v); } }else{ if(isVertical){ var v = this.value + increment; if(Edo.isValue(this.stopOffset) && v > this.stopOffset){ return; } this._setValue(v); }else{ var v = this.value + increment; if(Edo.isValue(this.stopOffset) && v > this.stopOffset){ return; } this._setValue(v); } } }, _startSpin: function(spinDirection, increment, spinTime){ this.spinDirection = spinDirection; this.spinTimer = this.doSpin.time(spinTime, this, [spinDirection, increment], true); }, _stopSpin: function(){ clearInterval(this.spinTimer); this.spinTimer = null; this.stopOffset = null; //这里也应该激发scrollComplete事件 if(this.canFireComplete){ this.completeScroll(); this.canFireComplete = false; } }, _onHandleDragStart: function(e){ //得到可拖拽的box区域, 将拖拽范围限定 this.moveBox = this.getMoveReginBox(); this.enableSyncScroll = false; if(!isIE8){ var sf = this; this.scrollTimer = setInterval(function(){ if(sf.direction == 'vertical'){ sf._setValue(sf._value); }else{ sf._setValue(sf._value); } }, this.scrollTime); } this.fireEvent('scrollstart', { type: 'scrollstart', source: this, direction: this.direction, value: this.value, maxValue: this.maxValue }); }, _onHandleDragMove: function(e){ var dm = e.source; var moveBox = this.moveBox; var isVertical = this.direction == 'vertical'; if(isVertical){ e.xy[0] =moveBox.x; if(e.xy[1] < moveBox.y) e.xy[1] = moveBox.y; if(e.xy[1] > moveBox.bottom) e.xy[1] = moveBox.bottom; //先设置一个_value属性, 用来后续的设置 this._value = this.createvalue(e.xy[1] - moveBox.y, moveBox.height); }else{ e.xy[1] =moveBox.y; if(e.xy[0] < moveBox.x) e.xy[0] = moveBox.x; if(e.xy[0] > moveBox.right) e.xy[0] = moveBox.right; this._value = this.createvalue(e.xy[0] - moveBox.x, moveBox.width); } if(isIE8){ if(this.dragTimer){ var d = new Date(); if(d - this.dragTimer >= this.scrollTime){ this.dragTimer = d; this._setValue(this._value); } } } }, _onHandleDragComplete: function(e){ this.enableSyncScroll = true; clearInterval(this.scrollTimer); if(Edo.isValue(this._value)){ this._setValue(this._value); } this._value = null; this.completeScroll(); }, completeScroll: function(){ this.fireEvent('scrollcomplete', { type: 'scrollcomplete', source: this, direction: this.direction, value: this.value }); }, _setValue: function(value){ if(!Edo.isValue(value)) return; if(value < 0) value = 0; if(value > this.maxValue) value = this.maxValue; if(this.value != value){ this.value = value; this.syncScroll(); this.fireEvent('scroll', { type: 'scroll', source: this, direction: this.direction, value: this.value }); } }, _setMaxValue: function(value){ if(value < 0 ) value = 0; if(this.maxValue != value){ this.maxValue = value; this.relayout('maxValue'); } }, //根据maxValue,maxValue, value, value,将handle定位 syncScroll: function(){ if(!this.el || this.enableSyncScroll == false) return; //根据当前的value/value,进行定位 var handleSize = this.getHandleSize(); if(handleSize != 0){ var handleOffset = this.getHandleOffset(handleSize); var offset = handleOffset + (this.direction == 'vertical' ? this.upHeight : this.upWidth); if(this.direction == 'vertical'){ this.handle.style.top = offset + 'px'; }else{ this.handle.style.left = offset + 'px'; } } } }); Edo.controls.ScrollBar.regType('scrollbar');