美文网首页我爱编程程序员
JavaScript实现简单的按键评星效果

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

作者: 立正小歪牙 | 来源:发表于2018-05-19 22:56 被阅读7次

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

    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还没有解决思路,如有大神指点感激不尽! (๑•̀ㅂ•́)و✧

    相关文章

      网友评论

        本文标题:JavaScript实现简单的按键评星效果

        本文链接:https://www.haomeiwen.com/subject/huzadftx.html