很酷的星级评分系统原生JS实现


Posted in Javascript onAugust 25, 2016

今天我又写了个很酷的实例:星级评分系统(可自定义星星个数、显示信息)

 sufuStar.star();使用默认值5个星星,默认信息
 var msg = [........]; sufuStar.star(10,msg);自定义星星个数为10、显示信息msg格式参考默认值,条数必须和星星个数一致; 

自己实现一些实例,有个好处,能增加应用各知识点的熟练度,还能检验出自己的薄弱项!一经发现,立即翻API文档恶补! 

不知道是不是我太笨,这个实例居然写了整整一天! 

不废话了,先说下这个实例涉及的知识点:
 1.用CSS的border来画个三角形,并用before来把它加到其它元素上;
 2.学习如何用CSS来定位元素;
 3.学习事件的代理;
 4.如何优化性能;
 5.String对象的match方法的应用,正则表达式的应用;
 6.注册事件与事件处理,需要兼容IE的写法;
 7.学习如何利用‘||'给变量设置默认值;
 8.简化代码:将可能要重复写的代码拿出来,单独写成一个函数; 

下面是带注释的完整代码,碰到不懂得就查文档吧,以我目前的水平只能写成这样了,若有好的建议,欢迎前辈指出!

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title></title>
 <style>
 *{
  margin: 0;
  padding: 0;
 }
 #star{
  position: absolute;
  left: 0;
  right: 0;
  top: 30px;
  bottom: 0;
  margin: auto;
  width: 80%;
  font-size: 12px;
 }
 #star-div{
  margin:5px;
  font-size: 0;
 }
 #star-div a{
  display: inline-block;
  width: 21px;
  height: 21px;
  background: url(http://files.cnblogs.com/files/susufufu/star0.gif) no-repeat;

 }
 #star-div .on{
  background: url(http://files.cnblogs.com/files/susufufu/star1.gif) no-repeat;
 }
 #star-info{
  position: absolute;
  top: 55px;
  left: -30px;
  display: none;
  width: 155px;
  height: 50px;
  padding: 2px;
  line-height: 17px;
  border-radius: 8px;
  background-color: gold;
  z-index: 5;
 }
 #star-info:before{
  content: '';
  border-bottom: 10px solid gold;
  border-left: 10px solid rgba(0,0,0,0);
  border-right: 10px solid rgba(0,0,0,0);
  position: absolute;
  left: 35px;
  top: -10px;
 }
 #star-span{line-height: 14px}
 #star-info strong,#star-span strong{
  color: red;
 }
 </style>
 <script>
 window.onload = function(){
  var sufuStar = function (){
  //工具函数
  function gbyId(id){return document.getElementById(id);}

  function addEvent(elem,type,func){ //兼容IE
   if(elem.addEventListener){
   elem.addEventListener(type,func,false)
   }else if(elem.attachEvent){
   elem.attachEvent('on'+type,func)
   }
  }
  function getIndex(event) { //兼容IE
   var e = event || window.event;
   var t = e.target || e.srcElement;
   if (t.tagName.toLowerCase() === 'a') {
   return parseInt(t.innerHTML);
   }
  }
  function showInfo(index,msg){
   var info = gbyId('star-info');
   info.style.display = 'block';
   info.style.left = index*21-51+'px';
   info.innerHTML = "<strong> "+index+'分 '+msg[index-1].match(/(.+)\|/)[1]+'<br />'+'</strong>'+msg[index-1].match(/\|(.+)/)[1];
  }
  function appenStar(elem,nums){
   var frag = document.createDocumentFragment(); //为了提高性能,因使用DocumentFragment一次性append,这样页面只重新渲染一次
   for(var i = 0;i<nums;i++){
   var a =document.createElement('a');
   a.innerHTML = i+1;
   a.href = "javascript:;"; //阻止浏览器的点击链接的默认行为
   frag.appendChild(a);
   }
   elem.appendChild(frag);
  }
  //主体函数
  function star(num,myMsg){
   var n = num||5; //当num有值则取其值,无值则取默认值5;
   var clickStar=curentStar=0; //clickStar保存点击状态
   var msg = myMsg||[
   "很不满意|差得太离谱,与卖家描述的严重不符,非常不满",
   "不满意|部分有破损,与卖家描述的不符,不满意",
   "一般|质量一般,没有卖家描述的那么好",
   "满意|质量不错,与卖家描述的基本一致,还是挺满意的",
   "非常满意|质量非常好,与卖家描述的完全一致,非常满意"
   ];
   var starContainer = gbyId('star-div');
   appenStar(starContainer,n);
   addEvent(starContainer,'mouseover',over); //采用事件代理模式(通过<a>标签的父元素starContainer来代理事件)
   addEvent(starContainer,'mouseout',out);
   addEvent(starContainer,'click',click);
   function over(event){
   if(getIndex(event)){ //若getIndex(event)取不到值,说明当前触发事件的目标不是<a>标签
    var index = getIndex(event);
    change(index);
    showInfo(index,msg);
   }
   }
   function out(event){
   change(); //将评分设为已点击状态clickStar
   gbyId('star-info').style.display = 'none'
   }
   function click(event) {
   if (getIndex(event)) {
    var index = getIndex(event);
    clickStar = index; //保存点击状态
    gbyId('star-info').style.display = 'none';
    gbyId('star-span').innerHTML = "<strong>" + index + '分 ' + msg[index - 1].match(/(.+)\|/)[1] + '</strong>'+'<br />'+ msg[index - 1].match(/\|(.+)/)[1];
   }
   }
   function change(index){
   curentStar = index||clickStar;
   for(var i=0;i<n;i++){
    starContainer.children[i].className = i<curentStar ? 'on' : ''
   }
   }
  }
  return {
   star:star
  }
  }(); //这里的()表示函数立即执行,这样变量sufuStar才能调用匿名函数的返回值star

  //调用执行: sufuStar.star(num,myMsg),参数可为空,参数num,myMsg将设为默认值
  sufuStar.star();
 }
 </script>
</head>
<body>
<div id="star">
 <span>点击星星打分:</span>
 <div id="star-div">
 </div>
 <span id="star-span"></span>
 <p id="star-info">
 </p>
</div>
</body>
</html>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
window.parent调用父框架时 ie跟火狐不兼容问题
Jul 30 Javascript
js获取当前日期代码适用于网页头部
Jun 27 Javascript
js点击出现悬浮窗效果不使用JQuery插件
Jan 20 Javascript
jQuery ajax serialize() 方法使用示例
Nov 02 Javascript
js实现Select列表内容自动滚动效果代码
Aug 20 Javascript
在页面中输出当前客户端时间javascript实例代码
Mar 02 Javascript
Node.js利用js-xlsx处理Excel文件的方法详解
Jul 05 Javascript
javascript实现文字无缝滚动效果
Aug 26 Javascript
vue slot 在子组件中显示父组件传递的模板
Mar 02 Javascript
如何在vue里添加好看的lottie动画
Aug 02 Javascript
jquery 动态遍历select 赋值的实例
Sep 12 jQuery
Vue中qs插件的使用详解
Feb 07 Javascript
jQuery 利用$.ajax 时获取原生XMLHttpRequest 对象的方法
Aug 25 #Javascript
轻松掌握JavaScript策略模式
Aug 25 #Javascript
Javascript 6里的4个新语法
Aug 25 #Javascript
Javascript实现代码折叠功能
Aug 25 #Javascript
深入浅出ES6之let和const命令
Aug 25 #Javascript
PhotoSwipe异步动态加载图片方法
Aug 25 #Javascript
相册展示PhotoSwipe.js插件实现
Aug 25 #Javascript
You might like
星际争霸任务指南——人族
2020/03/04 星际争霸
php通过sort()函数给数组排序的方法
2015/03/18 PHP
PHP读取大文件的多种方法介绍
2016/04/04 PHP
详解配置 Apache 服务器支持 PHP 文件的解析
2017/02/15 PHP
jquery构造器的实现代码小结
2011/05/16 Javascript
在Iframe中获取父窗口中表单的值(示例代码)
2013/11/22 Javascript
网页广告中JS代码的信息监听示例
2014/04/02 Javascript
jQuery控制TR显示隐藏的几种方法
2014/06/18 Javascript
js监听鼠标点击和键盘点击事件并自动跳转页面
2014/09/24 Javascript
easyui tree带checkbox实现单选的简单实例
2016/11/07 Javascript
bootstrap fileinput组件整合Springmvc上传图片到本地磁盘
2017/05/11 Javascript
JavaScript代码判断输入的字符串是否含有特殊字符和表情代码实例
2017/08/17 Javascript
requireJS模块化实现返回顶部功能的方法详解
2017/10/16 Javascript
nodejs简单实现TCP服务器端和客户端的聊天功能示例
2018/01/04 NodeJs
Mac下通过brew安装指定版本的nodejs教程
2018/05/17 NodeJs
jQuery实现为动态添加的元素绑定事件实例分析
2018/09/07 jQuery
JS函数进阶之prototy用法实例分析
2020/01/15 Javascript
JavaScrip如果基于url实现图片下载
2020/07/03 Javascript
[01:11:10]2014 DOTA2华西杯精英邀请赛 5 24 iG VS VG加赛
2014/05/26 DOTA
[40:12]Liquid vs Chaos 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/16 DOTA
python操作mongodb根据_id查询数据的实现方法
2015/05/20 Python
python实现简单socket通信的方法
2016/04/19 Python
安装Python和pygame及相应的环境变量配置(图文教程)
2017/06/04 Python
Python基础之文件读取的讲解
2019/02/16 Python
Python3.5运算符操作实例详解
2019/04/25 Python
18个Python脚本可加速你的编码速度(提示和技巧)
2019/10/17 Python
Python3+RIDE+RobotFramework自动化测试框架搭建过程详解
2020/09/23 Python
python包的导入方式总结
2021/03/02 Python
如何让Java程序执行效率更高
2014/06/25 面试题
天逸系统(武汉)有限公司Java笔试题
2015/12/29 面试题
《桥》教学反思
2014/04/09 职场文书
先进事迹演讲稿
2014/09/01 职场文书
领导班子群众路线与四风问题对照检查材料思想汇报
2014/10/11 职场文书
队名及霸气口号大全
2015/12/25 职场文书
Redis Cluster 字段模糊匹配及删除
2021/05/27 Redis
MySQL控制流函数(-if ,elseif,else,case...when)
2022/07/07 MySQL