评分星星控件

<!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; 1000px; height:80px; padding:20px;" data-mce-style="border: 1px solid black;  1000px; height: 80px; padding: 20px;"><!-- 评分星星 --></div>
</body>
</html>
View Code

一个较简单的 实现方法,功能也简单,但是满足绝大部分情况了

<!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/p/2808987.html