You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

267 lines
8.0 KiB
JavaScript

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

(function($){
$.zUI = $.zUI || {}
$.zUI.emptyFn = function(){};
$.zUI.asWidget = [];
/*
* core代码定义增加一个插件的骨架
*/
$.zUI.addWidget = function(sName,oSefDef){
//设置规范中的常量sFlagName、sEventName、sOptsName
$.zUI.asWidget.push(sName);
var w = $.zUI[sName] = $.zUI[sName] || {};
var sPrefix = "zUI" + sName
w.sFlagName = sPrefix;
w.sEventName = sPrefix + "Event";
w.sOptsName = sPrefix + "Opts";
w.__creator = $.zUI.emptyFn;
w.__destroyer = $.zUI.emptyFn;
$.extend(w,oSefDef);
w.fn = function(ele,opts){
var jqEle = $(ele);
jqEle.data(w.sOptsName,$.extend({},w.defaults,opts));
//如果该元素已经执行过了该插件,直接返回,仅相当于修改了配置参数
if(jqEle.data(w.sFlagName)){
return;
}
jqEle.data(w.sFlagName,true);
w.__creator(ele);
jqEle.on(jqEle.data(w.sEventName));
};
w.unfn = function(ele){
w.__destroyer(ele);
var jqEle = $(ele);//移除监听事件
if(jqEle.data(w.sFlagName)){
jqEle.off(jqEle.data(w.sEventName));
jqEle.data(w.sFlagName,false);
}
}
}
/*
* draggable
* 参数obj{
* bOffsetParentBoundary:是否以定位父亲元素为边界,
* oBoundary:指定元素left和top的边界值形如{iMinLeft:...,iMaxLeft:...,iMinTop:...,iMaxTop:...},与上一个参数互斥
* fnComputePosition:扩展函数,返回形如{left:...,top:...}的对象
* }
* 支持的自定义事件:
* "draggable.start":drag起始就是鼠标down后触发
* "draggable.move":drag过程中多次触发
* "draggable.stop":drag结束触发就是鼠标up后触发
*/
//注册draggable组件
$.zUI.addWidget("draggable",{
defaults:{
bOffsetParentBoundary:false,//是否以定位父亲元素为边界
oBoundary:null,//边界
fnComputePosition:null//计算位置的函数
},
__creator:function(ele){
var jqEle = $(ele);
jqEle.data($.zUI.draggable.sEventName,{
mousedown:function(ev){
var jqThis = $(this);
var opts = jqThis.data($.zUI.draggable.sOptsName);
jqThis.trigger("draggable.start");
var iOffsetX = ev.pageX - this.offsetLeft;
var iOffsetY = ev.pageY - this.offsetTop;
function fnMouseMove (ev) {
var oPos = {};
if(opts.fnComputePosition){
oPos = opts.fnComputePosition(ev,iOffsetX,iOffsetY);
}else{
oPos.iLeft = ev.pageX - iOffsetX;
oPos.iTop = ev.pageY - iOffsetY;
}
var oBoundary = opts.oBoundary;
if(opts.bOffsetParentBoundary){//如果以offsetParent作为边界
var eParent = jqThis.offsetParent()[0];
oBoundary = {};
oBoundary.iMinLeft = 0;
oBoundary.iMinTop = 0;
oBoundary.iMaxLeft = eParent.clientWidth - jqThis.outerWidth();
oBoundary.iMaxTop = eParent.clientHeight - jqThis.outerHeight();
}
if(oBoundary){//如果存在oBoundary将oBoundary作为边界
oPos.iLeft = oPos.iLeft < oBoundary.iMinLeft ? oBoundary.iMinLeft : oPos.iLeft;
oPos.iLeft = oPos.iLeft > oBoundary.iMaxLeft ? oBoundary.iMaxLeft : oPos.iLeft;
oPos.iTop = oPos.iTop < oBoundary.iMinTop ? oBoundary.iMinTop : oPos.iTop;
oPos.iTop = oPos.iTop > oBoundary.iMaxTop ? oBoundary.iMaxTop : oPos.iTop;
}
jqThis.css({left:oPos.iLeft,top:oPos.iTop});
ev.preventDefault();
jqThis.trigger("draggable.move");
}
var oEvent = {
mousemove:fnMouseMove,
mouseup:function(){
$(document).off(oEvent);
jqThis.trigger("draggable.stop");
}
};
$(document).on(oEvent);
}});
}
});
/*
* panel
* 参数obj{
* iWheelStep:鼠标滑轮滚动时步进长度
* sBoxClassName:滚动框的样式
* sBarClassName:滚动条的样式
* }
*/
$.zUI.addWidget("panel",{
defaults : {
iWheelStep:16,
sBoxClassName:"zUIpanelScrollBox",
sBarClassName:"zUIpanelScrollBar"
},
__creator:function(ele){
var jqThis = $(ele);
//如果是static定位加上relative定位
if(jqThis.css("position") === "static"){
jqThis.css("position","relative");
}
jqThis.css("overflow","hidden");
//必须有一个唯一的直接子元素,给直接子元素加上绝对定位
var jqChild = jqThis.children(":first");
if(jqChild.length){
jqChild.css({top:0,position:"absolute"});
}else{
return;
}
var opts = jqThis.data($.zUI.panel.sOptsName);
//创建滚动框
var jqScrollBox = $("<div style='position:absolute;display:none;line-height:0;'></div>");
jqScrollBox.addClass(opts.sBoxClassName);
//创建滚动条
var jqScrollBar= $("<div style='position:absolute;display:none;line-height:0;'></div>");
jqScrollBar.addClass(opts.sBarClassName);
jqScrollBox.appendTo(jqThis);
jqScrollBar.appendTo(jqThis);
opts.iTop = parseInt(jqScrollBox.css("top"));
opts.iWidth = jqScrollBar.width();
opts.iRight = parseInt(jqScrollBox.css("right"));
//添加拖拽触发自定义函数
jqScrollBar.on("draggable.move",function(){
var opts = jqThis.data($.zUI.panel.sOptsName);
fnScrollContent(jqScrollBox,jqScrollBar,jqThis,jqChild,opts.iTop,0);
});
//事件对象
var oEvent ={
mouseenter:function(){
fnFreshScroll();
jqScrollBox.css("display","block");
jqScrollBar.css("display","block");
},
mouseleave:function(){
jqScrollBox.css("display","none");
jqScrollBar.css("display","none");
}
};
var sMouseWheel = "mousewheel";
if(!("onmousewheel" in document)){
sMouseWheel = "DOMMouseScroll";
}
oEvent[sMouseWheel] = function(ev){
var opts = jqThis.data($.zUI.panel.sOptsName);
var iWheelDelta = 1;
ev.preventDefault();//阻止默认事件
ev = ev.originalEvent;//获取原生的event
if(ev.wheelDelta){
iWheelDelta = ev.wheelDelta/120;
}else{
iWheelDelta = -ev.detail/3;
}
var iMinTop = jqThis.innerHeight() - jqChild.outerHeight();
//外面比里面高,不需要响应滚动
if(iMinTop>0){
jqChild.css("top",0);
return;
}
var iTop = parseInt(jqChild.css("top"));
var iTop = iTop + opts.iWheelStep*iWheelDelta;
iTop = iTop > 0 ? 0 : iTop;
iTop = iTop < iMinTop ? iMinTop : iTop;
jqChild.css("top",iTop);
fnScrollContent(jqThis,jqChild,jqScrollBox,jqScrollBar,0,opts.iTop);
}
//记录添加事件
jqThis.data($.zUI.panel.sEventName,oEvent);
//跟随滚动函数
function fnScrollContent(jqWrapper,jqContent,jqFollowWrapper,jqFlollowContent,iOffset1,iOffset2){
var opts = jqThis.data($.zUI.panel.sOptsName);
var rate = (parseInt(jqContent.css("top"))-iOffset1)/(jqContent.outerHeight()-jqWrapper.innerHeight())//卷起的比率
var iTop = (jqFlollowContent.outerHeight()-jqFollowWrapper.innerHeight())*rate + iOffset2;
jqFlollowContent.css("top",iTop);
}
//刷新滚动条
function fnFreshScroll(){
var opts = jqThis.data($.zUI.panel.sOptsName);
var iScrollBoxHeight = jqThis.innerHeight()-2*opts.iTop;
var iRate = jqThis.innerHeight()/jqChild.outerHeight();
var iScrollBarHeight = iScrollBarHeight = Math.round(iRate*iScrollBoxHeight);
//如果比率大于等于1不需要滚动条,自然也不需要添加拖拽事件
if(iRate >= 1){
jqScrollBox.css("height",0);
jqScrollBar.css("height",0);
return;
}
jqScrollBox.css("height",iScrollBoxHeight);
jqScrollBar.css("height",iScrollBarHeight);
//计算拖拽边界,添加拖拽事件
var oBoundary = {iMinTop:opts.iTop};
oBoundary.iMaxTop = iScrollBoxHeight - Math.round(iRate*iScrollBoxHeight)+opts.iTop;
oBoundary.iMinLeft = jqThis.innerWidth() - opts.iWidth - opts.iRight;
oBoundary.iMaxLeft = oBoundary.iMinLeft;
fnScrollContent(jqThis,jqChild,jqScrollBox,jqScrollBar,0,opts.iTop);
jqScrollBar.draggable({oBoundary:oBoundary});
}
},
__destroyer:function(ele){
var jqEle = $(ele);
if(jqEle.data($.zUI.panel.sFlagName)){
var opts = jqEle.data($.zUI.panel.sOptsName);
jqEle.children("."+opts.sBoxClassName).remove();
jqEle.children("."+opts.sBarClassName).remove();
}
}
});
$.each($.zUI.asWidget,function(i,widget){
unWidget = "un"+widget;
var w = {};
w[widget] = function(args){
this.each(function(){
$.zUI[widget].fn(this,args);
});
return this;
};
w[unWidget] = function(){
this.each(function(){
$.zUI[widget].unfn(this);
});
return this;
}
$.fn.extend(w);
});
})(jQuery);