转载请注明: TheViper http://www.cnblogs.com/TheViper
当页面中有很多滚动条,它们相互嵌套,很不好看,这时就会模拟滚动条,并给这个滚动条好看的样式,使得页面美观。
模拟滚动条很多时候是去用jquery插件,然后写几行代码就搞定了。不过随着mvvm的快速发展,很多时候都懒得用jquery了,这就是本文的动机,本屌力求用简单的不依赖jquery只依赖mvvm(avalon) api的代码,完成一个简易的滚动条。
要求:
1.鼠标滚轮可以让滚动条工作,界面滚动
2.鼠标可以拖动滚动条并让界面滚动
3.页面resize时,滚动条根据页面尺寸变化,仍然可以工作
效果:
很显然,这个组件是基于拖动drag的,本屌又不想重新写,就只有改下ui框架的drag了,这里改的是easy js ui的drag组件。用easy js是因为注释比较多,代码简洁。
本屌把easy js ui的drag组件里的相应方法换成avalon api里的方法,删掉prototype里的方法及冗余代码
1 define('drag',['avalon-min'],function(avalon){ 2 function getBoundary(container, target) { 3 var borderTopWidth = 0, borderRightWidth = 0, borderBottomWidth = 0, borderLeftWidth = 0, cOffset = avalon(container) 4 .offset(), cOffsetTop = cOffset.top, cOffsetLeft = cOffset.left, tOffset = avalon(target) 5 .offset(); 6 borderTopWidth = parseFloat(avalon.css(container,'borderTopWidth')); 7 borderRightWidth = parseFloat(avalon.css(container,'borderRightWidth')); 8 borderBottomWidth = parseFloat(avalon.css(container,'borderBottomWidth')); 9 borderLeftWidth = parseFloat(avalon.css(container,'borderLeftWidth')); 10 cOffsetTop = cOffsetTop - tOffset.top + parseFloat(avalon(target).css('top')); 11 cOffsetLeft = cOffsetLeft - tOffset.left + parseFloat(avalon(target).css('left')); 12 return { 13 top : cOffsetTop + borderTopWidth, 14 right : cOffsetLeft + avalon(container).outerWidth() - avalon(target).outerWidth() 15 - borderRightWidth, 16 left : cOffsetLeft + borderLeftWidth, 17 bottom : cOffsetTop + avalon(container).outerHeight() - avalon(target).outerHeight() 18 - borderBottomWidth 19 }; 20 } 21 var drag = function(target, options) { 22 var defaults = { 23 axis:null, 24 container:null, 25 handle:null, 26 ondragmove:null 27 }; 28 var o =avalon.mix(defaults,options), 29 doc = target.ownerDocument, 30 win = doc.defaultView || doc.parentWindow, 31 originHandle=target, 32 isIE =!-[1,], 33 handle = isIE ? target :doc, 34 container = o.container ?o.container: null, 35 count = 0, 36 drag = this, 37 axis = o.axis, 38 isMove = false, 39 boundary, zIndex, originalX, originalY, 40 clearSelect = 'getSelection' in win ? function(){ 41 win.getSelection().removeAllRanges(); 42 } : function(){ 43 try{ 44 doc.selection.empty(); 45 } 46 catch( e ){}; 47 }, 48 down = function( e ){ 49 o.isDown = true; 50 var newTarget = target, 51 left, top, offset; 52 o.width = avalon(target).outerWidth(); 53 o.height = avalon(target).outerHeight(); 54 o.handle = handle; 55 left = avalon(newTarget).css( 'left' ); 56 top = avalon(newTarget).css( 'top' ); 57 offset = avalon(newTarget).offset(); 58 drag.left = left = parseInt( left ); 59 drag.top = top = parseInt( top ); 60 drag.offsetLeft = offset.left; 61 drag.offsetTop = offset.top; 62 originalX = e.pageX - left; 63 originalY = e.pageY - top; 64 if( (!boundary && container)){ 65 boundary = getBoundary(container, newTarget ); 66 } 67 if( axis ){ 68 if( axis === 'x' ){ 69 originalY = false; 70 } 71 else if( axis === 'y' ){ 72 originalX = false; 73 } 74 } 75 if( isIE ){ 76 handle.setCapture(); 77 } 78 avalon.bind(handle,'mousemove',move); 79 avalon.bind(handle,'mouseup',up); 80 if( isIE ){ 81 avalon.bind(handle,'losecapture',up); 82 } 83 e.stopPropagation(); 84 e.preventDefault(); 85 }, 86 move = function( e ){ 87 if( !o.isDown ){ 88 return; 89 } 90 count++; 91 if( count % 2 === 0 ){ 92 return; 93 } 94 var currentX = e.pageX, 95 currentY = e.pageY, 96 style = target.style, 97 x, y, left, right, top, bottom; 98 clearSelect(); 99 isMove = true; 100 if( originalX ){ 101 x = currentX - originalX; 102 if( boundary ){ 103 left = boundary.left; 104 right = boundary.right; 105 x = x < left ? left : 106 x > right ? right : 107 x; 108 } 109 drag.left = x; 110 drag.offsetLeft = currentX - e.offsetX; 111 style.left = x + 'px'; 112 } 113 if( originalY ){ 114 y = currentY - originalY; 115 if( boundary ){ 116 top = boundary.top; 117 bottom = boundary.bottom; 118 y = y < top ? top : 119 y > bottom ? bottom : 120 y; 121 } 122 drag.top = y; 123 drag.offsetTop = currentY - e.offsetY; 124 style.top = y + 'px'; 125 } 126 o.ondragmove.call(this,drag); 127 e.stopPropagation(); 128 }, 129 up = function( e ){ 130 o.isDown = false; 131 if( isIE ){ 132 avalon.unbind(handle,'losecapture' ); 133 } 134 avalon.unbind( handle,'mousemove'); 135 avalon.unbind( handle,'mouseup'); 136 if( isIE ){ 137 handle.releaseCapture(); 138 } 139 e.stopPropagation(); 140 }; 141 avalon(originHandle).css( 'cursor', 'pointer' ); 142 avalon.bind( originHandle,'mousedown', down ); 143 drag.refresh=function(){ 144 boundary=getBoundary(container,target); 145 }; 146 }; 147 return drag; 148 });