JavaScript | 动画显示比例的投票效果

HTML5学堂(码匠):一个简洁实用的投票效果如何使用原生JS来进行实现呢?同时动画显示比例的形式又需要依靠哪些技术来实现?是数学对象还是字符串操作,又或者是计时器加上函数封装吗?

本文主要内容

1. 效果展示与结构搭建

2. 实现投票计算功能

3. 数学对象、字符串转换方法等

4. 动画显示比例条

1. 效果展示与结构搭建

1.1 效果展示

使用表单元素搭建允许用户进行数据录入的结构,配合上逻辑强大、功能丰富的原生JS,实现完整的投票计算功能,其主要功能包括:数据计算、动画展示结果、数据格式的判断等。具体展示如下:

1.2 效果结构搭建

如上图,本效果主要是做了四个选项的投票计算,在结构上就应该会出现相对应的四个input元素。但是考虑到实际使用上可能投票选项并不是刚好就只是四个的前提下,所以针对结构的搭建,使用了通过JS来动态生成相应的投票选项,具体的代码如下:

var arr = ['码匠A', '码匠B', '码匠C', '码匠D'];
function init(num) {
    for (var i = 0; i < num; i++) {
        con.innerHTML += '<form><label for="">' + arr[i] + ' 投票人数:</label><input type="text" name="" id=""><b>数值上限500</b></form><div><strong>投票占比:</strong><em></em><span class="result"></span></div>';
    };
}init(4);

上述代码中,满足了选项个数的自定义设置,如果需要添加或者删除选项,只需要针对数组arr进行数组项的添加或者删除即可,这样的处理充分满足了使用者对于投票项数的管理与控制。

2. 实现投票计算功能

2.1 实现计算功能

实现投票功能的最核心在于实现计算功能,作为用户,只需要在每个input框中输入相关选项的数值即可。但是针对开发者来说,要做的就比较复杂,首先需要能够获取到用户输入的所有数值,进行求和操作,然后让每一个选项的数值除以总和得出所占百分比,最后让页面能够呈现出相应的占比值。其具体功能代码如下:

var sum = 0;
var vals = [];
this.style.background = '#ccc';
for (var i = 0; i < putIns.length; i++) {
    vals[i] = parseInt(putIns[i].value);
    sum += vals[i];
};
for (var i = 0; i < results.length; i++) {
    // 第四步变形 - 增加进度条
    var percent = vals[i] / sum * 100;
    prog[i].targetVal = (Math.round(percent) <= 1 ? 1 : Math.round(percent));
    sport(prog[i], {'width' : prog[i].targetVal}, 20);
    results[i].innerHTML = percent.toFixed(2) + '%';
};

2.2 实现输入控制

实现输入控制主要是为了让用户体验能够更好,主要需要实现的是用户输入非数值或者不输入数值而点了提交投票按钮时的提示。

实现用户输入非数值时是不允许显示投票计算结果,因为该功能仅仅只能针对数值做计算。在代码实现层面上,借助失焦函数blur(),在用户完成一个input的输入时就对该数值做判断。如果输入的是非纯数值或者聚焦了input而不输入值时,input的边框会变成红色来做出提醒;如果输入的是纯数值,则不会有提示或者变化。具体代码如下:

// 这段是控制功能增加的东西
for (var i = 0; i < putIns.length; i++) {
    putIns[i].judge = 1;
    putIns[i].onblur = function() {
        var val = Number(this.value);
        if (val != val || this.value == '' || val > 500) {
            this.style.borderColor = '#f00';
            this.judge = 1;
        } else {
            this.style.borderColor = '#ccc';
            this.judge = 0;
        }
    }
};

3. 数学对象、字符串转换方法等

3.1 数学对象

上文实现投票计算代码中针对数值的计算,借助了数学对象Math中的round()方法,其主要的作用是为数值实现四舍五入的效果,用以配合最后的显示结果中出现对百分数保留两位数值。具体如下:

prog[i].targetVal = (Math.round(percent) <= 1 ? 1 : Math.round(percent));

3.2 字符串转换方法

实现投票功能必然是数值间的计算,但是用value属性从表单中获取数值时,通常得到的都是字符串类型的数据,所以需要对其进行字符串转换。上文中借助了parseInt()这个方法,针对用户输入的数值进行字符串转换,具体如下:

// 借助parseInt()方法获取数值型的值,然后做求和功能
vals[i] = parseInt(putIns[i].value);
sum += vals[i];

4. 动画显示比例条

4.1 获取渲染后的样式

在实现投票计算功能时,需要让计算的结果以对应的比例出现,此时就需要获取之前以结果值设置的样式值,然后把这个样式值拿来做渐变操作。但是获取设置的样式值是需要针对不同的浏览器来做相关的处理,其具体代码如下:

/*
* 功能:获取渲染后标签的样式,element是标签的对象,property是标签样式属性值
* 参数:element是元素对象,property是样式属性
*/
function getStyle(element, property){
    var proValue = null;
    if (!document.defaultView) {
     proValue = element.currentStyle[property];    
    } else {
     proValue = document.defaultView.getComputedStyle(element)[property];
    }
    return proValue;
}

4.2 实现动画控制比例条

使用原生JS实现动画的变化,类似于搭建一个动画类库的操作,其主要使用到的知识点有:for…in语句获取属性、计时器控制动画的持续性变化等。在实际书写的时候这部分内容的逻辑会比较复杂,但是所有的操作都遵循着从初始位置出发,速度变化越来越小的动画实现思路。具体如下:

function sport(ele, json, changeStep){
    clearInterval(ele.timer);
    ele.timer = setInterval(function(){
        var timerjudge = true;// 默认所有属性都到达终点值


        for(propAttr in json) {
            var starVal = parseInt(getStyle(ele, propAttr));
            var distance = Math.abs(json[propAttr] - starVal);
            var speed = Math.ceil( distance / changeStep);
 
            if (starVal < json[propAttr]) {
                starVal += speed;
            } else {
                starVal -= speed;
            }


            if (distance < 3) {
                starVal = json[propAttr];
            };


            // 只要任何一个属性没有到底终点,timerjudge为false
            if (starVal != json[propAttr]) {
                timerjudge = false;
            };    
            ele.style[propAttr] = starVal + "px";
        }


        if (timerjudge) {
            clearInterval(ele.timer);
        };
    }, 30);
}

总结

动画显示比例条的投票效果,针对使用层面来说,算是一个比较简洁明了的功能;针对代码层面来说,充分的体现了原生JS的逻辑性与复杂性。如上文的代码,大家如果看的不是很明白,可查看完整的代码逻辑:http://codepen.io/majiang/pen/ggEKxL

原文发布于微信公众号 - HTML5学堂(h5course-com)

原文发表时间:2017-02-17

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏彭湖湾的编程世界

【CSS/JS】如何实现单行/多行文本溢出的省略(...)--老司机绕过坑道的正确姿势

写前端UI的朋友们也许都遇到过这样的问题:我们需要实现这样一个需求,在一个父级元素中隐藏一个可能过长的文本: 这个文本可能是单行的: ? 也可能是多行的: ? ...

1938
来自专栏企鹅号快讯

D3.js 满足你对数据可视化的一切幻想

D3.js D3的全称是Data-Driven Documents(数据驱动的文档),是一个用来做数据可视化的JavaScript函数库,而JavaScript...

2708
来自专栏JetpropelledSnake

RESTful源码笔记之RESTful Framework的APIview, Viewset总结分析

官方文档:http://www.django-rest-framework.org/ drf为我们提供强大的通用view的功能,本博客对这些view进行简要的总...

571
来自专栏应用案例

D3.js 满足你对数据可视化的一切幻想

D3.js D3的全称是Data-Driven Documents(数据驱动的文档),是一个用来做数据可视化的JavaScript函数库,而JavaScript...

21510
来自专栏CRPER折腾记

CSS-Next : CSS预处理器简单写法的替代者, 想了解下么?

借助相关的插件我们可以把新的特性降级到 css3乃至一些特性降级到css2.1...无缝过渡

792
来自专栏小白安全

妙用JavaScript绕过XSS过滤-----小白安全博客

基于DOM的XSS漏洞利用 Mavo框架会创建一个名为$url的对象,该对象能够为开发人员提供访问GET参数的便捷方法。例如,如果你想访问GET参数“x”...

38412
来自专栏.NET后端开发

Highcharts使用指南

摘要 Highcharts图表控件是目前使用最为广泛的图表控件。本文将从零开始逐步为你介绍Highcharts图表控件。通过本文,你将学会如何配置Highcha...

2715
来自专栏kalifaの日々

GCJ 2008Round1AA 菜鸟踩坑(C++)

踩到的坑: 不同于POJ,GCJ有两个测试用例的文档,供你在本地得到输出,我开始的时候下载文档之后直接把文档中的数据复制出来,运行代码时贴上去,也就是,从标准输...

2475
来自专栏机器之心

资源 | 简单快捷的数据处理,数据科学需要注意的命令行

1455
来自专栏前端新视界

网页中添加下划线的方法汇总及优缺点

本文主要介绍了添加下划线样式的几乎所有方法,并且比较了每一种方法的优缺点。没想到之前一直没有注意的下划线还有这么多玄机奥秘! 本文由 nzbin 翻译,艾凌风...

17510

扫描关注云+社区