今天介绍ExtJS的组件开发,这里以星级评分为示例,首先来看看效果图:
然后是功能操作:鼠标移动到五个星星上面时,会有tooltip显示当前的分值。如图:鼠标悬停在第四颗星星时前四颗星星显示高亮笑脸,当点击下去时锁定笑脸并且设定份数为4。
然后我们来说一下实现原理,Ext的组件基本单元是Ext.Component,所以自定义组件可以继承Component,然后显示部分直接用html来显示,包括css和动态事件都可以直接在html上编辑添加。
接下来我们来看代码:
Ext.define('Pactera.widget.StarRating', {
alias:"widget.starRating",
extend: 'Ext.Component',
afterRender:function(){
this.callParent();
},
//label: 'score',//
//labelWidth: 60,
//lableAlign:'right',//left,center,right
//aMsg: [],
/*[
"很不满意|差得太离谱,与卖家描述的严重不符,非常不满",
"不满意|部分有破损,与卖家描述的不符,不满意",
"一般|质量一般,没有卖家描述的那么好",
"满意|质量不错,与卖家描述的基本一致,还是挺满意的",
"非常满意|质量非常好,与卖家描述的完全一致,非常满意"
]*/
width: 275,
height: 50,
padding: 10,
style: {
color: '#000000',
backgroundColor:'#FFFFFF'
},
initComponent: function(){
var me = this;
var date = new Date();
var dateTime = date.getTime();
var starId = me.id?"star_"+me.id:"star"+dateTime;
var label = me.label?me.label:'评分';
var labelWidth = me.labelWidth?me.labelWidth-13:87;
var labelAlign = me.lableAlign?me.lableAlign:'right';
var thisWidth = me.width?me.width:130;
var aMsg = [
"Unacceptable|Unacceptable",
"Poor|Poor",
"Fair|Fair",
"Good|Good",
"Excellent|Excellent"
]
if(me.aMsg){
aMsg = me.aMsg;
}
var html = '<div id="'+ starId +'" class="star" >'
+ '<span >'+ label + '</span>'
+ '<span>:</span>'
+ '<ul>'
+ '<li><a href="javascript:;">1</a></li>'
+ '<li><a href="javascript:;">2</a></li>'
+ '<li><a href="javascript:;">3</a></li>'
+ '<li><a href="javascript:;">4</a></li>'
+ '<li><a href="javascript:;">5</a></li>'
+ '</ul>'
+'<span></span>'
+'<p></p>'
+'</div>'
this.html = html;
this.listeners = {
'boxready':function(){
var oStar = document.getElementById(starId);
var aLi = oStar.getElementsByTagName("li");
var oUl = oStar.getElementsByTagName("ul")[0];
var oSpan = oStar.getElementsByTagName("span")[1];
var oP = oStar.getElementsByTagName("p")[0];
var i = iScore = me.iStar = 0;
for (i = 1; i <= aLi.length; i++)
{
aLi[i - 1].index = i;
//鼠标移过显示分数
aLi[i - 1].onmouseover = function ()
{
fnPoint(this.index);
//浮动层显示
oP.style.display = "block";
//计算浮动层位置
oP.style.left = oUl.offsetLeft + this.index * this.offsetWidth - 104 + "px";
//匹配浮动层文字内容
oP.innerHTML = "<em><b>" + this.index + "</b> " + aMsg[this.index - 1].match(/(.+)\|/)[1] + "</em>" + aMsg[this.index - 1].match(/\|(.+)/)[1]
};
//鼠标离开后恢复上次评分
aLi[i - 1].onmouseout = function ()
{
fnPoint();
//关闭浮动层
oP.style.display = "none"
};
//点击后进行评分处理
aLi[i - 1].onclick = function ()
{
me.iStar = this.index;
oP.style.display = "none";
//oSpan.innerHTML = "<strong>" + (this.index) + " 分</strong> (" + aMsg[this.index - 1].match(/\|(.+)/)[1] + ")"
me.value = this.index;
}
}
//评分处理
function fnPoint(iArg)
{
//分数赋值
iScore = iArg || me.iStar;
for (i = 0; i < aLi.length; i++) aLi[i].className = i < iScore ? "on" : "";
}
var setValue = function(score){
me.iStar = score;
fnPoint(score);
}
me.setValue = setValue;
}
}
this.callParent();
}
});
css样式代码:
.star ul{list-style-type:none;}
.star{position:relative;margin:0px auto;}
.star ul,.star span{float:left;display:inline;height:19px;line-height:19px;}
.star ul{margin:0 10px;padding-start: 0px;-webkit-padding-start: 0px;-moz-padding-start: 0px;}
.star li{float:left;width:24px;cursor:pointer;text-indent:-9999px;background:url(http://sandbox.runjs.cn/uploads/rs/285/beoxl0jq/star.png) no-repeat;}
.star strong{color:#f60;padding-left:10px;}
.star li.on{background-position:0 -28px;}
.star p{position:absolute;top:20px;width:179px;height:67px;display:none; background:url(./p_w_picpath/tooltipbg.gif) no-repeat; z-index:100000;padding:7px 10px 0;}
.star p em{color:#f60;display:block;font-style:normal;}
下面是调用代码:
var starRating = Ext.create('Pactera.widget.StarRating',{
label:'Is it a good question?',
width:450,
labelWidth:250,
name:'starRating'
});
下面说几个注意点:
1、动态响应事件必须要写在boxready之内,因为我们操作的对象是document,所以必须在页面渲染生成document以后。
2、因为是评分组件,就会有读和写,读的话就是选中星级后读取几星,这里我们设定的直接是value,而写我们设定了setValue()方法,所以在form表单加载时,该组件就可以直接加载到该分数的样式。
3、tooltip的内容同样是可以自定义的,我们只要在实例化该组件时传入参数便可以自定义tooltip提示。
系统开发中肯定会有各种各样的组件,而我们只要发挥想象,都能够将这些功能组件模块化,从而达到共用。