上一篇写了第一个基础控件,本篇我们开始编写可见控件com.ui.window.js,首先,在component文件夹下面添加ui文件夹,并在ui文件夹下添加com.ui.window.js文件,并添加初始化方法,init、create、render、_doResize方法
window类继承com.baseObject类,
init 重写基类的方法,主要添加dom占位元素,是否由dom创建标志两个参数
并从dom元素对象中获取option属性,合并到类option属性并调用渲染方法,
create 为基类调用的创建方法,用于初始化变量,比如键盘事件,鼠标事件,宽,高等属性
render 为跟据属性,渲染或重构dom元素
afterRender为渲染后函数,
_doResize 则为跟据宽,高等属性,设置dom元素的位置或宽高等,
因为dom元素多需要添加样式,这里写了针对样式控制的方法,setStyle, addStyle, clearStyle, delStyle,另外,dom元素都有margin, padding, border等属性,为了续方便,添加了简易的读取边距函数,
这里我们有些函数用到了下划线开头,我们这里定义这种函数为私有函数,
详细代码如下,
/**
* 可见窗口基类.
* 创建: QZZ
* 日期: 2014-04-06
*/
(function(undefined) {
nameSpace("com.ui");
com.ui.window = Extend(com.baseObject, {
/**
* 初始化函数.
* @param option 属性
* @param control DOM元素
* @param isDom 是否dom元素, 如果是在html页面上布局,
* 则option已自动解析,
*/
init:function(option, control, isDom) {
this.base(option);
if(typeof control != "undefined") {
//获取dom元素
this.thisWindow = control;
if(!isDom) {
//读取属性
var op = control.attributes.option;
if(typeof op != "undefined") {
op = eval("(" + op.nodeValue + ")");
}
if(typeof op != "undefined") {
for(var key in op) {
this.option[key] = op[key];
}
}
}
this.name = control.id || control.name;
}
this.logInfo("window.init");
this.render();
this.afterRender();
},
/**
* 对象创建函数.
*/
create:function() {
this.base();
this.className = "com.ui.window";
this.logInfo("window.create");
this.eventList = {};
this.keyBoard = {
DOWN:40,
UP:38,
LEFT:37,
RIGHT:39,
ENTER:13,
C:10,
V:86,
X:88,
Z:90
};
this.mouseType = {mtLeft : "L",
mtRight: "R"};
this.parent;
//处理宽高,顶点,左边
this.option.top = this._domValue(this.option.top, 0);
this.option.left = this._domValue(this.option.left, 0);
//绝对顶、左点
this._atop = null;
this._aleft = null;
//宽高
this.option.width = this._domValue(this.option.width, 10);
this.option.height = this._domValue(this.option.height, 10);
//内外边距
this.option.margin = this._domValue(this.option.margin,0);
this.option.padding = this._domValue(this.option.padding,0);
this.option.border = this.option.border||"";
this.focus = false;
//面板选择
this.hasSelect = false;
this._eventList = {};
this.body = null;
},
/**
* 渲染函数.
*/
render:function() {
this.logInfo("window.render");
if(typeof this.thisWindow == "undefined") {
this.thisWindow = this.createElement("div");
}
this.setStyle(this.thisWindow, "winStyle");
//处理大小变量
if(this._hasResize()) {
this._doResize();
}
},
/**
* 渲染后执行.
*/
afterRender:function(){
var _this = this;
this.thisWindow.onmouseup = function() {
_this.hasSelect = true;
};
//系统事件
this._sysEvent();
},
/**
* 执行变化调整事件.
* @return 返回状态
*/
_doResize:function() {
if(!this._update) return false;
this.logBegin("_doResize");
//边距处理
if(this.thisWindow.style.margin != this.option.margin + "px") {
this.thisWindow.style.margin = this.option.margin + "px";
}
if(this.thisWindow.style.padding != this.option.padding + "px") {
this.thisWindow.style.padding = this.option.padding + "px";
}
if(this.option.border !== "") {
this.thisWindow.style.border = this.option.border;
}
//计算长宽
var bw = this._getRectWidth();
var bh = this._getRectHeight();
if(bw <= 0) {
bw = 1;
}
bw += "px";
if(bh <= 0) {
bh = 1;
}
bh += "px"
var isResize = false;
var msg = "";
//处理大小
if(this.thisWindow.style.width != bw) {
msg += this.getName() + " width:" + this.thisWindow.style.width + " to " + bw + " ";
this.thisWindow.style.width = bw;
isResize = true;
}
if(this.thisWindow.style.height != bh) {
msg += this.getName() + " height:" + this.thisWindow.style.height + " to " + bh + " ";
this.thisWindow.style.height = bh;
isResize = true;
}
this.logEnd("_doResize " + msg);
return isResize;
},
/**
* 样式设置.
* @param tab 元素
* @param className 样式名
* @param doCss 设计样式
*/
setStyle:function(tab, className, doCss){
doCss = doCss || true;
if(className instanceof Array) {
//在元素上设置格式数组对象
tab.cssAry = className;
var cn = className.join(" ");
if(tab.className != cn && doCss) {
tab.className = cn;
}
} else {
//直接设置样式
if (tab.className != className) {
if(doCss) {
tab.className = className;
}
tab.cssAry = [className];
}
}
},
/**
* 添加样式.
* @param tab 元素
* @param className 样式名
* @param doCss 处理样式
*/
addStyle:function(tab, className, doCss) {
doCss = doCss || true;
if(typeof tab.cssAry != "undefined") {
//检查重复
var i = 0, len = tab.cssAry.length
for(; i < len; i++) {
if(tab.cssAry[i] == className) {
break;
}
}
//添加样式
if(i >= len) {
tab.cssAry.push(className);
}
} else {
tab.cssAry = [className];
}
if(doCss) {
//设计样式到dom
var ncs = tab.cssAry.join(" ");
if(ncs !== tab.className) {
tab.className = ncs;
}
}
},
/**
* 清除样式.
* @param tab 元素
* @param doCss 执行样式.
*/
clearStyle:function(tab, doCss) {
if(typeof tab.cssAry != "undefined") {
tab.cssAry = [];
}
doCss = doCss || true;
if(doCss && tab.className !== "") {
tab.className = "";
}
},
/**
* 删除样式.
* @param tab 元素
* @param className 样式名
* @param doCss 处理样式
*/
delStyle:function(tab, className, doCss) {
if(typeof tab.cssAry != "undefined") {
//查找需要删除的样式名
var i = 0, len = tab.cssAry.length;
for(; i < len; i++) {
if(tab.cssAry[i] == className) {
break;
}
}
if(i < len) {
tab.cssAry.splice(i, 1);
}
}
doCss = doCss || true;
if(doCss) {
var ncs = tab.cssAry.join(" ");
if(ncs !== tab.className) {
tab.className = ncs;
}
}
},
/**
* 解析dom元素的值.
* @param value 值
*/
_domValue:function(value, defValue) {
var vt = typeof value;
var defValue = defValue || 0;
if(vt == "string") {
value = value.replace(/px/, "");
if(this.isNotEmpty(value) && !isNaN(value)) {
value = parseInt(value, 10);
} else {
value = defValue;
}
} else if(vt != "number") {
value = defValue;
}
return value;
},
/**
* 大小是否发生变化.
*/
_hasResize:function() {
return !(this.thisWindow.style.top == this.option.top + "px"
&& this.thisWindow.style.left == this.option.left + "px"
&& this.thisWindow.style.width == this._getRectWidth() + "px"
&& this.thisWindow.style.height == this._getRectHeight() + "px");
},
/**
* 获取内宽.
* @return 返回宽度
*/
_getRectWidth:function() {
return this.getWidth() - (this._getBorderLeft()
+ this._getBorderRight()
+ this._getMarginLeft()
+ this._getMarginRight()
+ this._getPaddingLeft()
+ this._getPaddingRight());
},
/**
* 获取内高.
* @return 返回高度
*/
_getRectHeight:function() {
return this.getHeight() - (this._getBorderTop()
+ this._getBorderBottom()
+ this._getMarginTop()
+ this._getMarginBottom()
+ this._getPaddingTop()
+ this._getPaddingBottom());
},
/**
* 获取边左线.
* @param el 元素
* @return 返回宽度
*/
_getBorderLeft:function(el) {
var el = el || this.thisWindow;
return this._domValue(el.style.borderLeftWidth, 0);;
},
/**
* 获取右边线
* @param el 元素
* @return 返回宽度
*/
_getBorderRight:function(el) {
var el = el || this.thisWindow;
return this._domValue(el.style.borderRightWidth, 0);
},
/**
* 获取上边线
* @param el 元素
* @return 返回宽度
*/
_getBorderTop:function(el) {
var el = el || this.thisWindow;
return this._domValue(el.style.borderTopWidth, 0);
},
/**
* 获取下边线
* @param el 元素
* @return 返回宽度
*/
_getBorderBottom:function(el) {
var el = el || this.thisWindow;
return this._domValue(el.style.borderBottomWidth, 0);
},
/**
* 获取左外边距
* @param el 元素
* @return 返回宽度
*/
_getMarginLeft:function(el) {
var el = el || this.thisWindow;
return this._domValue(el.style.marginLeft, 0);
},
/**
* 获取右外边距
* @param el 元素
* @return 返回宽度
*/
_getMarginRight:function(el) {
var el = el || this.thisWindow;
return this._domValue(el.style.marginRight, 0);
},
/**
* 获取上外边距
* @param el 元素
* @return 返回宽度
*/
_getMarginTop:function(el) {
var el = el || this.thisWindow;
return this._domValue(el.style.marginTop, 0);
},
/**
* 获取下外边距
* @param el 元素
* @return 返回宽度
*/
_getMarginBottom:function(el) {
var el = el || this.thisWindow;
return this._domValue(el.style.marginBottom, 0);
},
/**
* 获取左内边距.
* @param el 元素
* @return 返回宽度
*/
_getPaddingLeft:function(el) {
var el = el || this.thisWindow;
return this._domValue(el.style.paddingLeft, 0);
},
/**
* 获取右内边距.
* @param el 元素
* @return 返回宽度
*/
_getPaddingRight:function(el) {
var el = el || this.thisWindow;
return this._domValue(el.style.paddingRight, 0);
},
/**
* 获取上内边距.
* @param el 元素
* @return 返回宽度
*/
_getPaddingTop:function(el) {
var el = el || this.thisWindow;
return this._domValue(el.style.paddingTop, 0);
},
/**
* 获取下内边距.
* @param el 元素
* @return 返回宽度
*/
_getPaddingBottom:function(el) {
var el = el || this.thisWindow;
return this._domValue(el.style.paddingBottom, 0);
},
/**
* 获取body元素宽度.
* @return body宽度
*/
_getBodyWidth:function() {
if(this.browser.safari) {
return document.documentElement.clientWidth;
} else {
return this.body().width();
}
},
/**
* 获取body元素高度.
* @return body高度
*/
_getBodyHeight:function() {
if(this.browser.safari) {
return document.documentElement.clientHeight;
} else {
return this.body().height();
}
},
/**
* 返回当前窗口.
*/
getRectDom:function() {
return this.thisWindow;
},
/**
* 返回窗口body.
*/
body:function(){
if(typeof this.winBody == "undefined") {
this.winBody = document.getElementsByTagName("body")[0];
}
return this.winBody;
},
/**
* 获取高度.
* @return 返回高度
*/
getHeight:function() {
return this.option.height;
},
/**
* 设置高度.
* @param height 高度
* @param doRs 执行变更函数
*/
setHeight:function(height, doRs) {
this.option.height = height;
//this.logInfo("Window.setHeight");
doRs = doRs || true;
if(doRs && this._hasResize()) {
this._doResize();
}
},
/**
* 获取宽度
* @return 返回宽度
*/
getWidth:function() {
return this.option.width;
},
/**
* 设置宽度.
* @param width 宽度
* @param doRs 执行变更函数
*/
setWidth:function(width, doRs){
this.option.width = width;
//this.logInfo("Window.setWidth");
doRs = doRs || true;
if(doRs && this._hasResize()) {
this._doResize();
}
},
/**
* 设置顶点.
* @param top 顶点
* @param doRs 执行变更函数
*/
setTop:function(top, doRs) {
this.option.top = top;
this.logInfo("Window.setTop");
doRs = doRs || true;
if(doRs && this._hasResize()) {
this._doResize();
}
},
/**
* 获取当前顶点位置
* @return 顶点坐标
*/
getTop:function() {
return this.option.top;
},
/**
* 设置左边位置.
* @param left 左边位置
* @param doRs 执行变更函数
*/
setLeft:function(left, doRs) {
this.option.left = left;
this.logInfo("Window.setLeft");
doRs = doRs || true;
if(doRs && this._hasResize()) {
this._doResize();
}
},
/**
* 获取左边位置值.
* @return 返回
*/
getLeft:function() {
return this.option.left;
}
});
})();
有了上面的类,我们便可以在test.html文件中添加我们的自定义控件,如下<div>便是我们新增加的dom元素,这里我们把id设置为test, code为com.ui.window类,option中称添加height,width属性
<!DOCTYPE html>
<head><title>test</title>
<script src="../script/common/init.js" type="text/javascript"></script>
</head>
<body>
<div id='test1' code='com.ui.window' option='{"height":"100","width":"100"}'></div>
</body>
</html>
同时,我们在样式文件com.comStyle.css中,添加一个样式,如下
注意,如果option没有设置对应的height,width的时候,将会以样式的宽高为准
.winStyle {
border:1px solid #C3D2E6;
font-size:12px;
width:10px;
height:10px;
}
这样,我们就可以通过浏览器打开test.html文件查看效果,会发现一个100px的蓝边正方形,
可下载附件的代码