/* * Balancebeam Widget Grid_Plugin_Scroller 1.0 * * Description : Support drag head for exchange columns * Copyright 2011 * License : MIT * Author : yangzz * Mail : balancebeam@163.com * * Depends: * balancebeam/lib/widget/grid/beam.grid.js */ (function( $, undefined ) { $.ui.grid.scroller = function(grid){ this.grid = grid; this._create(); } $.ui.grid.scroller.prototype = { _create : function(){ var grid = this.grid, contentsNode = grid.contentsNode; //define vertical scroller element var html = []; html.push("
"); html.push("
"); html.push("
"); html.push("
"); html.push("
"); html.push("
"); html.push("
"); html.push("
"); html.push("
"); this.yscrollerNode = $(html.join("")); $("*",this.yscrollerNode).attr("UNSELECTABLE","on"); this.yscrollerBarNode = $(">.bar",this.yscrollerNode); contentsNode.append(this.yscrollerNode); //define horizontal scroller element html = []; html.push("
"); html.push("
"); html.push("
"); html.push("
"); html.push("
"); html.push("
"); html.push("
"); html.push("
"); html.push("
"); this.xscrollerNode = $(html.join("")); $("*",this.xscrollerNode).attr("UNSELECTABLE","on"); this.xscrollerBarNode = $(">.bar",this.xscrollerNode); contentsNode.append(this.xscrollerNode); this.funnelEvents(); grid.subscribe("resize.grid-scroller",this,"resize"); }, //bind event funnelEvents : function(){ var self = this; //bind event this.yscrollerNode.mousedown(function(e){ $.stopEvent(e); var target = e.target; switch(target.className){ case "top" : self.scrollToTop(1); break; case "bottom" : self.scrollToBottom(1); break; case "y-scroller" : //TODO break; default : if(/^bar/.test(target.className)){ self.scrollMoveY(e); } } }); this.xscrollerNode.mousedown(function(e){ $.stopEvent(e); var target = e.target; switch(target.className){ case "left" : self.scrollToLeft(); break; case "right" : self.scrollToRight(); break; case "x-scroller" : //TODO break; default : if(/^bar/.test(target.className)){ self.scrollMoveX(e); } } }); //定义鼠标的滚轮事件 this.grid.contentsNode.bind( jQuery.browser.mozilla ? "DOMMouseScroll.grid-scroller":"mousewheel.grid-scroller",function(e){ if(!self.grid.normalView.viewport.yscroller){ return; } $.stopEvent(e); var delta = 0, step =3; if (null!=e.wheelDelta) { delta = e.wheelDelta/120; } else if (null!=e.detail) { delta = -e.detail/3; }else if(null!=window.event.wheelDelta){ delta = window.event.wheelDelta/120; } else if (null!=window.event.detail) { delta = -window.event.detail/3; } if(delta>0){ //向上滚动 self.scrollToTop(delta*step); } else{//向下滚动 self.scrollToBottom(-delta*step); } }); }, scrollToBottom : function(step){ var viewport = this.grid.normalView.viewport; if(viewport.endRowEdge){ return; } viewport.beginRowIndex+=step; var h = viewport.rowHeight* (viewport.rowCount-viewport.beginRowIndex); for(;h0){ viewport.beginRowIndex = viewport.beginRowIndex - step; if(viewport.beginRowIndex<0){ viewport.beginRowIndex = 0; } } else{ return; } } viewport.endRowEdge = false; this.grid.doYScroll(); this.positionY(); }, scrollMoveY : function(e){ var clientY =e.clientY, handleY = -1, self = this, viewport = this.grid.normalView.viewport, top = this.yscrollerBarNode.css("top"); top = "auto"==top ? (this.yscrollerHeight - 16 - this.yscrollerBarHeight) : parseInt(top,10); document.body.setCapture && document.body.setCapture(); function mousemoveEvent(e){ $.stopEvent(e); clearTimeout(handleY); var newTop = top + e.clientY - clientY, endRowEdge = false; //上边界 if(newTop<16){ newTop = 16; } //下边界 else if(newTop+self.yscrollerBarHeight+16>self.yscrollerHeight){ newTop = self.yscrollerHeight - self.yscrollerBarHeight -16; endRowEdge = true; } self.yscrollerBarNode.css("top",newTop+"px"); var rowIndex = Math.floor((newTop -16) * (viewport.rowsHeight - viewport.height) / ((self.yscrollerHeight -32 - self.yscrollerBarHeight) * viewport.rowHeight)); if(viewport.beginRowIndex == rowIndex && endRowEdge==viewport.endRowEdge){ return false; } handleY = setTimeout(function(){ viewport.endRowEdge = endRowEdge; viewport.beginRowIndex = rowIndex; self.grid.doYScroll(); },10); return false; } function mouseupEvent(e){ document.body.releaseCapture && document.body.releaseCapture(); $(document).unbind("mousemove",mousemoveEvent); $(document).unbind("mouseup",mouseupEvent); } $(document).bind("mousemove",mousemoveEvent); $(document).bind("mouseup",mouseupEvent); }, scrollToRight : function(){ var normalView = this.grid.normalView, viewport = normalView.viewport; if(viewport.endColumnEdge){ return; } viewport.beginColumnIndex++; var w = 0; viewport.visibleColumns = 0; for(var i=viewport.beginColumnIndex,column;column=normalView.columns[i];i++){ w += column.width || this.grid.options.columnWidth; viewport.visibleColumns++; if(w>=viewport.width){ break; } } viewport.endColumnEdge = false; if(w=viewport.width){ break; } } } viewport.endColumnEdge = false; normalView.renderContent(); this.positionX(); }, scrollMoveX : function(e){ var clientX =e.clientX, handleX = -1, self = this, normalView = this.grid.normalView, viewport = normalView.viewport, left = this.xscrollerBarNode.css("left"); left = "auto"==left ? (this.xscrollerWidth - 16 - this.xscrollerBarWidth) : parseInt(left,10); document.body.setCapture && document.body.setCapture(); function mousemoveEvent(e){ $.stopEvent(e); clearTimeout(handleX); var newLeft = left + e.clientX - clientX, endColumnEdge = false, columnIndex = 0, visibleColumns = 0; //下边界 if(newLeft+self.xscrollerBarWidth+16>self.xscrollerWidth){ newLeft = self.xscrollerWidth - self.xscrollerBarWidth -16; endColumnEdge = true; self.xscrollerBarNode.css({ "left" : "auto", "right" : "16px" }); var w = 0; for(var i=normalView.columns.length-1,column;column=normalView.columns[i];i--){ w += column.width || self.grid.options.columnWidth; visibleColumns++; if(w>=viewport.width){ columnIndex = i; break; } } } else{ //上边界 if(newLeft<16){ newLeft = 16; } self.xscrollerBarNode.css({ "left" : newLeft+"px", "right" : "auto" }); var scrollWidth = (newLeft -16) * (normalView.getHeaderTableWidth() - viewport.width) / (self.xscrollerWidth -32 - self.xscrollerBarWidth); var w = 0; for(var i=0,column;column=normalView.columns[i];i++){ w += column.width || self.grid.options.columnWidth; if(w>=scrollWidth){ columnIndex=i; break; } } w = 0; for(var i=columnIndex,column;column=normalView.columns[i];i++){ w += column.width || self.grid.options.columnWidth; visibleColumns++; if(w>=viewport.width){ break; } } for(;w.contents>.placeholder",grid.gridElement).remove(); if(viewport.yscroller && viewport.xscroller){ this.yscrollerHeight = this.yscrollerHeight - grid.scrollerOffset; this.xscrollerWidth = this.xscrollerWidth - grid.scrollerOffset; $(">.contents",grid.gridElement).append($("
")) } this.xscrollerNode.width(this.xscrollerWidth); this.yscrollerNode.height(this.yscrollerHeight); if(viewport.yscroller){ this.yscrollerBarHeight = viewport.height * (this.yscrollerHeight-30)/viewport.rowsHeight; if(this.yscrollerBarHeight<15){ this.yscrollerBarHeight = 15; } this.yscrollerBarNode.height(this.yscrollerBarHeight); this.positionY(); } if(viewport.xscroller){ this.xscrollerBarWidth = viewport.width * (this.xscrollerWidth-30)/viewport.headerTableWidth; if(this.xscrollerBarWidth<15){ this.xscrollerBarWidth = 15; } this.xscrollerBarNode.width(this.xscrollerBarWidth); this.positionX(); } }, positionY : function(){ var grid = this.grid, viewport = grid.normalView.viewport; this.yscrollerBarNode.css("bottom","auto"); if(viewport.endRowEdge){ this.yscrollerBarNode.css({ "top" : "auto", "bottom" : "16px" }); } else{ var h = viewport.beginRowIndex * viewport.rowHeight, y= h * (this.yscrollerHeight-30- this.yscrollerBarHeight) / (viewport.rowsHeight - viewport.height); this.yscrollerBarNode.css("top",(y+16)+"px"); } }, positionX : function(){ var grid = this.grid, normalView = grid.normalView, viewport = normalView.viewport; this.xscrollerBarNode.css("right","auto"); if(viewport.endColumnEdge){ this.xscrollerBarNode.css({ "left" : "auto", "right" : "16px" }); } else{ var w = normalView.getScrollLeft(); var x = w * (this.xscrollerWidth - this.xscrollerBarWidth - 30) / (normalView.getHeaderTableWidth() - viewport.width); this.xscrollerBarNode.css("left",(x+16)+"px"); } }, destroy : function(){ this.yscrollerNode.unbind("mousedown"); this.xscrollerNode.unbind("mousedown"); this.grid.contentsNode.unbind(jQuery.browser.mozilla ? "DOMMouseScroll.grid-scroller":"mousewheel.grid-scroller"); delete this.yscrollerNode; delete this.xscrollerNode; } }; $.ui.grid.plugins.register("scroller",$.ui.grid.scroller); })(jQuery);