
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<style>
/*大星星 start*/
.bigStarBox{
position:relative;
display:inline-block;
*display:inline;
*zoom:1;
float:left;
width:100px;
cursor:pointer;
}
.bigStarBox span{
cursor:pointer;
display: inline-block;
*display:inline;
*zoom:1;
width:18px;
height:18px;
background:url(http://images.cnblogs.com/cnblogs_com/ecalf/431722/o_start_big_2.gif) no-repeat -36px center;
margin-right:2px;
}
.bigStarBox .selected{
background-position:left center;
}
.bigStarBox .halfStar{
background-position:-18px center;
}
.bigStarBox .valueLabel{
height:18px;
}
/*大星星 end*/
/*小星星 start*/
.smallStarBox{
position:relative;
display:inline-block;
*display:inline;
*zoom:1;
float:left;
width:75px;
cursor:pointer;
}
.smallStarBox span{
cursor:pointer;
display: inline-block;
*display:inline;
*zoom:1;
width:13px;
height:13px;
background:url(http://images.cnblogs.com/cnblogs_com/ecalf/431722/o_start_small_2.gif) no-repeat -26px center;
margin-right:2px;
}
.smallStarBox .selected{
background-position:left center;
}
.smallStarBox .halfStar{
background-position:-13px center;
}
.smallStarBox .valueLabel{
display: inline-block;
*display:inline;
*zoom:1;
height:13px;
}
/*小星星 end*/
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript">
// <!--[CDATA[
function Star(options){
this.max=5; //所有星星被选中
this.min=0; //没有星星被选中
this.scale=1; //每星数值
this.value=0; //控件的值
this.column = 5; //每行最多显示星星数量
this.deicle = true; //是否允许小数点显示半星
this.locked=false; //锁定控件的值
this.staticMod = false; //仅用于显示不能交互设置值
this.bigMode=true; //false 小星,true 大星
this.modStyle=["smallStarBox","bigStarBox"];//小星、大星的样式类
this.starStyle={"unselected":"unselected","selected":"selected","hover":"selected","half":"halfStar"}; //星星各种状态下的样式类
this.tipConf=['非常不满意','不满意','一般','满意','非常满意'];
this.container=null; //id or domObj,not jQuery obj
this.dom = null; //自动创建
this.valueLabel = null; //显示值的dom节点,如果没有通过options指定则自动创建
this.callbacks =[]; //设置值后的回调函数
this.init(options||{});
}
Star.prototype={
init:function(options){
var host = this;
for(var key in options){
host[key]=options[key];
}
if(typeof(host.tipConf=="function")){
host.tipConf = host.tipConf.call(host);
}
if(Object.prototype.toString.call(host.tipConf)!="[object Array]"){
host.tipConf = [];
}
host.create();
return host;
},
create:function(){//绘制评分星星
var host = this;
if(typeof(host.container)=='string'){
host.container = document.getElementById(host.container);
}
host.dom = document.createElement("div");
host.container.appendChild(host.dom);
if(!host.valueLabel){
host.valueLabel = document.createElement("span");
host.valueLabel.className = "valueLabel";
host.container.appendChild(host.valueLabel);
}else if(typeof(host.valueLabel)=="string"){
host.valueLabel = document.getElementById(host.valueLabel);
}
var hoder = $(host.dom);
hoder.addClass(host.modStyle[host.bigMode*1]);
var starsIndex = 0;
var starsNum = (host.max-host.min)/host.scale;
var starsCount = Math.ceil(starsNum);
do{
var star = $('<span></span>');
hoder.append(star);
starsIndex++;
if(starsIndex==1){ //每行的星星数量
if(host.column>1){
hoder.width((star.width()+2) *host.column);
}
}
}while(starsIndex<starsCount);
hoder.children("span").hover(
function(e){
if(host.locked||host.staticMod){ return; }
clearTimeout(host.switchClassTime);
var targetStart = $(e.target);
targetStart.prevAll().attr("class",host.starStyle['hover']);
targetStart.attr("class",host.starStyle["hover"]);
var unselectedStarts = targetStart.nextAll();
if(unselectedStarts.length){
if(host.starStyle['unselected']){
unselectedStarts.attr("class",host.starStyle['unselected']);
}else{
unselectedStarts.removeAttr("class");
}
}
var tip = host.tipConf[targetStart.index()];
host.showValue(tip||host.getValue(targetStart.index()+1));
},
function(e){
if(host.locked||host.staticMod){ return; }
var targetStart = $(e.target);
host.switchClassTime=setTimeout(function(){
if(host.starStyle["unselected"]){
hoder.children("span").attr("class",host.starStyle['unselected']);
}
host.showValue('');
},100);
}
).click(function(e){
if(host.staticMod){return;}
var targetStart = $(e.target);
var selectedClass = host.starStyle['selected'];
if(host.locked&&targetStart.hasClass(selectedClass)
&&(
!targetStart.next().length
//在修改器样式之前判断
||!targetStart.next().hasClass(selectedClass)
)
){ //修改值,解锁处于自由滑动选择状态
host.setLock(false);
}else{//设置值之后暂时锁定
host.setLock(true);
}
targetStart.prevAll().attr("class",selectedClass);
targetStart.attr("class",selectedClass);
var unselectedStarts = targetStart.nextAll();
if(unselectedStarts.length){
if(host.starStyle['unselected']){
unselectedStarts.attr("class",host.starStyle['unselected']);
}else{
unselectedStarts.removeAttr("class");
}
}
host.setValue();
var tip = host.tipConf[targetStart.index()];
host.showValue(tip||host.getValue());
});
if(host.value>host.min){//初始化设置值不触发事件
var callbacks = host.callbacks;
host.callbacks = [];
host.setValue(host.value);
host.callbacks = callbacks;
}
return host;
},
setLock:function(frag){
var host = this;
if(arguments[0]!==undefined){
host.locked=!!frag;
}
return host;
},
showValue:function(value){
var host = this;
host.valueLabel && (host.valueLabel.innerHTML = value+'');
return host;
},
getValue:function(startIndex){//从 1 开始,第几颗星的分值
var host = this;
if(startIndex*1>0){
return ((startIndex*1+1)*host.scale+host.min);
}
return host.value;
},
setValue:function(val){
var host = this;
if(!arguments.length){
var starsSelected = $(host.dom).children("."+host.starStyle['selected']);
host.value = host.min+starsSelected.length*host.scale;
if($(host.dom).children("."+host.starStyle['half']).length){
host.value += host.scale*0.5;
}
}else{
if(val<host.min){
val=host.min;
}else if(val>host.max){
val = host.max;
}
if(!host.deicle){
host.value = Math.round(val);
}else{
host.value = parseFloat(val);
}
var starSelectedNum = Math.ceil((host.value - host.min)/host.scale);
var tip = host.tipConf[starSelectedNum-1];
$.each($(host.dom).children("span"),function(index,item){
if(starSelectedNum<=0){
return false;
}
if(starSelectedNum==1&&host.value%1!=0){//最后一星
$(item).attr("class",host.starStyle['half']);
}else{
$(item).attr("class",host.starStyle['selected']);
}
if(starSelectedNum==1){
$(item).nextAll().attr("class",host.starStyle['unselected']);
}
starSelectedNum--;
});
host.showValue(tip||host.getValue());
}
//fire callbacks
$.each(host.callbacks||[],function(index,fun){
fun.call(host);
});
return host;
},
setTips:function(tips){//an array or a function return an array
var host = this;
if(typeof(tipConf)=='function'){
tips = tips.call(host);
}
if(Object.prototype.toString.call(tips)=="[object Array]"){
host.tipConf = tips;
}
return host;
},
setCallback:function(f){
var host = this;
if(!arguments.length||f.constructor!=Function){
return host;
}
host.callbacks.push(f);
return host;
}
};
//useage
$(document).ready(function(){
var mystars = window.stars = new Star({container:'stars',
min:-6,
max:5,
staticMod:false,
bigMode:true,
column:5,
value:4,
tipConf:function(){ var host = this; var arr = []; for(var i=0;i<((host.max-host.min)/host.scale);i++){ arr[i] = "score:"+((i+1)*host.scale+host.min); } return arr;},
callbacks:[function(){ console.log('value>>>',this.value); }]
}).setValue(2);
});
// ]]-->
</script>
<div id="stars" style="border:1px solid black; width:1000px; height:80px; padding:20px;" data-mce-style="border: 1px solid black; width: 1000px; height: 80px; padding: 20px;"><!-- 评分星星 --></div>
</body>
</html>
一个较简单的 实现方法,功能也简单,但是满足绝大部分情况了
<!DOCTYPE html>
<html>
<head>
<title></title>
<style>
/* 评分星星 begin */
.starScoreBox{
width:90px;
}
.starScoreBox .starScoreHolder{
position:relative;
margin-left:-18px;
float: left;
}
.starScoreBox .starScoreHolder span{
background: url(http://images.cnblogs.com/cnblogs_com/ecalf/431722/o_start_big_2.gif) no-repeat -36px center;
width: 18px;
height: 18px;
float: left;
position: relative;
left: 18px;
cursor:pointer;
}
.starScoreBox .starScoreHolder span:hover,.starScoreBox .selected span{
background-position:left center;
}
.starScoreBox .selectEnd span{
background-position:-36px center;
}
.starScoreBox span.starScoreStore{
font-weight: bold;
text-indent: 25px;
}
/*评分星星 end*/
</style>
</head>
<body>
<div class="starScoreBox">
<div id="holder" class="starScoreHolder">
<span>
<span>
<span>
<span>
<span id="starValue" class="starScoreStore"> </span>
</span>
</span>
</span>
</span>
</div>
</div>
<script>
var removeClass = function(node,className){
node.className = node.className.replace(new RegExp('\\s\*'+className,'g'),'');
};
var hasClass = function(node,className){
return new RegExp('(?:\\s|^)'+className+'(?:\\s|$)').test(node.className);
};
var addClass = function(node,className){
if(!hasClass(node,className)){
node.className += ' '+className;
}
};
var holder = document.getElementById("holder");
holder.addEventListener('click',function(e){
var target = e.target;
var div = this.nodeName.toLowerCase();
var span = target.nodeName.toLowerCase();
var store = document.getElementById('starValue');
if(span!='span') return;
if(hasClass(target,'selectEnd')){
removeClass(this,'selected');
removeClass(target,'selectEnd');
this.setAttribute('data-value',0);
store.innerHTML = '';
}else{
addClass(this,'selected');
addClass(target,'selectEnd');
var n = 1;
var p = target.parentNode;
while(p.nodeName.toLowerCase()=='span'){
removeClass(p,'selectEnd');
p = p.parentNode;
n++;
}
var c = target.children[0];
while(c){
removeClass(c,'selectEnd');
c = c.children[0];
}
holder.setAttribute("data-value",n);
store.innerHTML = n;
}
},false);
holder.addEventListener('mouseover',function(e){
if(hasClass(this,'selected')){
return;
}
var target = e.target||e.srcElement;
if(target.nodeName.toLowerCase()!='span'){
return;
}
var store = document.getElementById('starValue');
var n = 1;
var p = target.parentNode;
while(p.nodeName.toLowerCase()=='span'){
p = p.parentNode;
n++;
}
store.innerHTML = n;
},false);
holder.addEventListener('mouseout',function(e){
var store = document.getElementById('starValue');
store.innerHTML = this.getAttribute('data-value')*1||'';
},false);
</script>
</body>
</html>
来源:https://www.cnblogs.com/ecalf/archive/2012/12/08/2808987.html
