很酷的星级评分系统原生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 相关文章推荐
IE JS编程需注意的内存释放问题
Jun 23 Javascript
网页自动跳转代码收集
Sep 27 Javascript
jQuery html()等方法介绍
Nov 18 Javascript
js 剪切板应用clipboardData详细解析
Dec 17 Javascript
JS中取二维数组中最大值的方法汇总
Apr 17 Javascript
canvas压缩图片转换成base64格式输出文件流
Mar 09 Javascript
Vue.js 60分钟快速入门教程
Mar 28 Javascript
JS+CSS实现下拉刷新/上拉加载插件
Mar 31 Javascript
Angular 2 利用Router事件和Title实现动态页面标题的方法
Aug 23 Javascript
多个vue子路由文件自动化合并的方法
Sep 03 Javascript
微信小程序实现点击卡片 翻转效果
Sep 04 Javascript
vue引入Excel表格插件的方法
Apr 28 Vue.js
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
php中的时间处理
2006/10/09 PHP
php+AJAX传送中文会导致乱码的问题的解决方法
2008/09/08 PHP
php下载远程文件类(支持断点续传)
2008/11/14 PHP
单点登录 Ucenter示例分析
2013/10/29 PHP
thinkphp的静态缓存用法分析
2014/11/29 PHP
PHP对称加密算法(DES/AES)类的实现代码
2017/11/14 PHP
php5对象复制、clone、浅复制与深复制实例详解
2019/08/14 PHP
基于javascript的Form表单验证
2016/12/29 Javascript
JavaScript实现替换字符串中最后一个字符的方法
2017/03/07 Javascript
页面间固定参数,通过cookie传值的实现方法
2017/05/31 Javascript
JS实现字体背景跑马灯
2020/01/06 Javascript
js实现轮播图效果 z-index实现轮播图
2020/01/17 Javascript
vue中 v-for循环的用法详解
2020/02/19 Javascript
[02:27]2014DOTA2国际邀请赛 VG赛后采访:更大的挑战在等着我们
2014/07/13 DOTA
关于反爬虫的一些简单总结
2017/12/13 Python
python docx 中文字体设置的操作方法
2018/05/08 Python
python twilio模块实现发送手机短信功能
2019/08/02 Python
如何使用python的ctypes调用医保中心的dll动态库下载医保中心的账单
2020/05/24 Python
python基于pygame实现飞机大作战小游戏
2020/11/19 Python
css3如何绘制一个圆圆的loading转圈动画
2018/01/09 HTML / CSS
html5 canvas绘制网络字体的常用方法
2019/08/26 HTML / CSS
Hush Puppies澳大利亚官网:舒适的男女休闲和正装鞋
2019/08/24 全球购物
大学生四年生活自我鉴定
2013/11/21 职场文书
CAD制图人员的自荐信
2014/02/07 职场文书
2014年社区庆元旦活动方案
2014/03/08 职场文书
运动会的口号
2014/06/09 职场文书
中学生打架检讨书
2014/10/13 职场文书
任命书怎么写
2015/03/02 职场文书
小爸爸观后感
2015/06/15 职场文书
海底两万里读书笔记
2015/06/26 职场文书
预防职务犯罪警示教育心得体会
2016/01/15 职场文书
《狼牙山五壮士》教学反思
2016/02/17 职场文书
2019年新郎保证书3篇
2019/10/17 职场文书
在K8s上部署Redis集群的方法步骤
2021/04/27 Redis
Python实现单例模式的5种方法
2021/06/15 Python
微信小程序APP的事件绑定以及传递参数时的冒泡和捕获
2022/04/19 Javascript