JavaScript实现简单的按键评星效果

最近有个项目需要在页面上通过点亮星星的形式显示一个评分结果:

1、适合对多个对象进行评分

2、需要展示分数从0开始每颗星星点亮的变化

刚开始找到一个starability.css纯css插件,这个插件可以实现点击星星实现星星点亮的酷炫的动画效果。

插件地址:starability

但是项目要求不能通过鼠标直接点击星星来点亮,还需要展示每颗星星点亮的过程,所以我打算通过url参数来控制对象和预设分数,通过点击页面上的显示结果按钮,评分展示出来,需要借助JavaScript。

页面效果

演示地址:JavaScript按钮评分效果demo

html结构

我选择了插件中星星向上滚动的效果starability-slot,html结构如下:

<div class="starability-container">
  <h1>标题</h1>
  <form>
    <fieldset class="starability-slot" id="slot">
      <input type="radio" id="rate1-2" name="rating" value="1" />
      <label for="rate1-2" title="Terrible">1 stars</label>
      <input type="radio" id="rate2-2" name="rating" value="2" />
      <label for="rate2-2" title="Not good">2 stars</label>
      <input type="radio" id="rate3-2" name="rating" value="3" />
      <label for="rate3-2" title="Average">3 stars</label>
      <input type="radio" id="rate4-2" name="rating" value="4" />
      <label for="rate4-2" title="Very good">4 stars</label>
      <input type="radio" id="rate5-2" name="rating" value="5" />
      <label for="rate5-2" title="Amazing">5 star</label>
    </fieldset>
  </form>
</div>
<a class="btn" id="btn">显示结果</a>

获取url参数

要获取url参数www.xxxx.com?tit=标题&score=5中的tit和score值,需要用到getUrlParam函数。

一般我们用到getUrlParam函数的时候最后一行一般是return unescape(results[1]);,但是因为我需要从url获取中文参数,这样会导致乱码,因此改用decodeURI解码。

function getUrlParam(name) {
  name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
  var regexS = "[\\?&]" + name + "=([^&#]*)";
  var regex = new RegExp(regexS);
  var results = regex.exec(window.location.href);
  if (results == null)
    return "";
  else
    return decodeURI(results[1]);//浏览器会将url中的中文参数进行encodeURI编码,所以要通过js使用decodeURI进行解码,return unescape(results[1]);适合gb2312
}

定义两个全局变量:

var tit = getUrlParam("tit");//标题
var score = getUrlParam("score");//星星数:1-5分

点亮星星

使用setTimeout函数控制每颗星星点亮的间隔时间,每隔0.5s调用一次starlight函数,直到到达设定分数。

var i = 0;
var t;
function starlight() {
  if (score > 5) score = 5;
  if (score < 1) score = 1;
  if (i < score) {
    var slot = document.getElementById("slot");
    var stars = slot.getElementsByTagName("input");
    var labels = slot.getElementsByTagName("label");
    var styleStr = "background-position: 0 -240px;transition: background-position .7s;";//240px为星星图片宽度
    stars[i].setAttribute("style", styleStr);
    labels[i].setAttribute("style", styleStr);
    t = setTimeout(starlight, 500);
    i++;
  }
}

打开页面就要显示设定好的标题,点亮星星是通过点击按钮后才显示。

//获取标题
function getTit(tit) {
  if (tit == "") {
    alert("请填写tit值");
    return false;
  }
  var h1 = document.getElementsByTagName("h1");
  h1[0].innerHTML = tit;
}
window.onload=getTit(tit);
//点击按钮调用 starlight函数
document.getElementById("btn").addEventListener("click", function () {
  starlight();
});

一个简单的评星效果就实现了。

项目优化

由于需要每次更改url参数score的值,必须预先设定好分数,操作起来不太方便。

改用键盘数字1-5键控制星星点亮数,其他键清空。

演示地址:JavaScript按键评分效果demo

完整代码:下载地址

清除样式函数

由于clearStyle和starlight函数都需要引用stars、labels,需要把stars、labels改为全局变量。

var slot = document.getElementById("slot");
var stars = slot.getElementsByTagName("input");
var labels = slot.getElementsByTagName("label");

clearStyle函数如下:

function clearStyle() {
  i = 0;
  for (j = 0; j < stars.length; j++) {
    stars[j].removeAttribute("style");
    labels[j].removeAttribute("style");
  }
}

starlight函数可以简化如下:

function starlight() {
  if (score > labels.length) score = labels.length;
  if (score < 0) score = 0;
  if (i < score) {
    var styleStr = "background-position: 0 -240px;transition: background-position .5s;";//240px为星星图片宽度
    stars[i].setAttribute("style", styleStr);
    labels[i].setAttribute("style", styleStr);
    t = setTimeout(starlight, 500);
    i++;
  }
}

按键执行函数

把之前click侦听按钮函数改为onkeydown函数,switch函数对应键值事件。

需要注意的是,数字键盘中的1-5键的码值与字母键盘是不一致的,下面函数我用的是字母键盘中的数字键码值。

字母键盘键码值keyCode对应表 图片来源:百度经验
数字键盘键码值keyCode对应表 图片来源:百度经验
//键盘执行函数
document.onkeydown = function (event) {
  var e = event || window.event || arguments.callee.caller.arguments[0];
  var keyNum = e && e.keyCode;
  switch (keyNum) {
    case 49://键盘数字键1
    score = 1;
    break;
    case 50://键盘数字键2
    score = 2;
    break;
    case 51://键盘数字键3
    score = 3;
    break;
    case 52://键盘数字键4
    score = 4;
    break;
    case 53://键盘数字键5
    score = 5;
    break;
    default:
    score = 0;
    break;
  }
  clearStyle();
  starlight();
}

改写后的页面可以不用刷新就能控制分数了。

遇到的问题

优化过后的代码遇到一个小bug,按下1到5键过后,如果继续按下1-5其中一个键,第一个input和label的样式并未清除,如下图:

clearStyle函数中console位置

console输出如下:

console结果

1、我在页面一开始调用了一个consloe.log(stars[0]),确认初始状态第一个input并未有style;

2、为按下5键的状态,可以看到clearStyle函数中star[0]即第一个input中的style并未被清除,但是2-5的input中的style已被清除;

3、为接着按下2键的状态,第一个input中的style依然并未被清除;

4、为再接着按下其他键的状态,第一个input中的style被清除了。

目前这个bug还没有解决思路,如有大神指点感激不尽! (๑•̀ㅂ•́)و✧

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,802评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,109评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,683评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,458评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,452评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,505评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,901评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,550评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,763评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,556评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,629评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,330评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,898评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,897评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,140评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,807评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,339评论 2 342

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,579评论 18 139
  • HTML 5 HTML5概述 因特网上的信息是以网页的形式展示给用户的,因此网页是网络信息传递的载体。网页文件是用...
    阿啊阿吖丁阅读 3,815评论 0 0
  • 第3章 基本概念 3.1 语法 3.2 关键字和保留字 3.3 变量 3.4 数据类型 5种简单数据类型:Unde...
    RickCole阅读 5,095评论 0 21
  • 本节介绍各种常见的浏览器事件。 鼠标事件 鼠标事件指与鼠标相关的事件,主要有以下一些。 click 事件,dblc...
    许先生__阅读 2,413评论 0 4
  • tbox之前提供的stackfull协程库,虽然切换效率已经非常高了,但是由于每个协程都需要维护一个独立的堆栈,内...
    waruqi阅读 833评论 0 50