一个贷款计算器Web应用

提示:该例子集中使用了诸多技术,展示了真实环境下的客户端JavaScript(包括HTML和CSS)编程。

文章目录

    • 一个贷款计算器Web应用
  • 前言
    • 图1-1
  • 一、主要功能点:
  • 二、代码实现
    • 1.HTML
    • 2.CSS
    • 3.JavaScript
  • 总结

前言

tips:在看代码之前应该先阅读本段文字。你不需要理解所有内容,代码中有着完整的注释,至少你应该能正确运行这段代码得到如图1-1所示的界面。这里的例子展示了诸多JavaScript语言核心特性,同样展示了重要的客户端JavaScript技术:

图1-1


一、主要功能点:

  • 如何在文档中查找元素
  • 如何通过表单input元素来获取用户的输入数据
  • 如何通过文档元素来设置HTML内容
  • 如何将数据存储在浏览器中
  • 如何使用脚本发起HTTP请求
  • 如何利用元素绘图

二、代码实现

1.HTML

代码如下:

<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>用JavaScript实现贷款计算器</title></head><body><table><tr><th>输入贷款数据 :</th><td></td><th>贷款余额,累计权益,利息支出</th></tr><tr><td>贷款金额 ($):</td><td><input id="amount" onchange="calculate();"></td><td rowspan="8"><canvas id="graph" width="400" height="250"></canvas></td></tr><tr><td>年利率 (%):</td><td><input id="apr" onchange="calculate();"></td></tr><tr><td>偿还期限 (years):</td><td><input id="years" onchange="calculate();"></td></tr><tr><td>Zipcode (to find lenders):</td><td><input id="zipcode" onchange="calculate();"></td></tr><tr><th>支付金额 :</th><td><button onclick="calculate();">Calculate</button></td></tr><tr><td>每月的付款 :</td><td>$<span class="output" id="payment"></span></td></tr><tr><td>总付款 :</td><td>$<span class="output" id="total"></span></td></tr><tr><td>总利息 :</td><td>$<span class="output" id="totalinterest"></span></td></tr><tr><th>赞助商:</th><td colspan=2>向有一定经济能力的放款人申请贷款。<div id="lenders"></div></td></tr></table><footer id="copyright">Copyright 2021.5.5 by Crease the blog diary</footer>
</body>
</html>

注:这是一个HTML表格,其中包含元素可以用来输入数据。程序将在’‘span’‘元素中显示计算结果,这些元素都具有类似’‘interset’‘和’‘years’‘的id,这些id将在表格下面的JavaScript代码中用到。我们注意到,有一些input元素定义了’‘onchange’‘或’‘onclick’'的事件处理程序,以便用户在输入数据或者点击inputs时执行指定的JavaScript代码段。

2.CSS

代码如下:

<style>.output{font-weight: bold;}/* 计算结果为粗体 */th,td{vertical-align: top;}/* 表格单元格对其方式为顶端对齐 */#payment{text-decoration: underline;}/* 定义id="payment"的元素样式 */#graph{border: solid black 1px;}/* 图标有一个1像素的边框 */#copyright{margin: 13% 0;text-align: center;color: gray;}
</style>

CSS样式表:定义了程序输出的样式。

3.JavaScript

代码如下:

<script type="text/javascript">"use strict";/* 如果浏览器支持的话,则开启ECMAScript5的严格模式 *//*这里的脚本定义了calculate()函数,在HTML代码中绑定事件处理程序时会调用它;这个函数从<input>元素中读取数据,计算贷款赔付信息,并将结果显示在<span>元素中;同样,这里还保存了用户数据,展示了放款人链接并绘制出了图表*/function calculate(){//查找文档中用于输入输出的元素var amount = document.getElementById("amount");var apr = document.getElementById("apr");var years = document.getElementById("years");var zipcode = document.getElementById("zipcode");var payment = document.getElementById("payment");var total = document.getElementById("total");var totalinterest = document.getElementById("totalinterest");//假设所有的输入输出都是合法的,将从input元素中获取输入数据//将百分比格式转换为小数格式,并从年利率转换为月利率//将年度赔付转换为月度赔付var principal = parseFloat(amount.value);var interest = parseFloat(apr.value)/100/12;var payments = parseFloat(years.value)*12;//现在计算月度赔付的数据var x = Math.pow(1 + interest,payments);//Math.pow()进行幂次运算var monthly = (principal * x * interest) / (x - 1);//如果结果没有超过JavaScript能表示的数字范围,且用户的输入也正确//这里所展示的结果就是合法的if(isFinite(monthly)){//将数据填充至输出字段的位置,四舍五入到小数点后两位数字payment.innerHTML = monthly.toFixed(2);total.innerHTML = (monthly * payments).toFixed(2);totalinterest.innerHTML = ((monthly * payments) - principal).toFixed(2);//将用户的输入数据保存下来,这样在下次访问时也能取到数据save(amount.value,apr.value,years.value,zipcode.value);//找到并展示本地放贷人,但忽略网络错误try{//捕获这段代码抛出的所有异常getLenders(amount.value,apr.value,years.value,zipcode.value);}catch(e){}//忽略这些异常//最后,用图表展示贷款余额、利息和资产收益chart(principal,interest,monthly,payments);}else{//计算结果不是数字或者是无穷大,意味着输入数据是非法或不完整的//清空之前的输出数据payment.innerHTML = "";     //清空元素的文本内容total.innerHTML = "";totalinterest.innerHTML = "";chart();     //不传参数的话就是清除图表}}/* 将用户的输入保存至localStorage对象的属性中这些属性在再次访问时还会继续保存在原位置如果你在浏览器中按照file://URL的方式直接打开本地文件,则无法在某些浏览器中使用存储功能(比如FireFox)而通过Http打开文件是可行的*/function save(amount,apr,years,zipcode){if(window.localStorage){//只有在浏览器支持的时候才运行这里的代码localStorage.loan_amount = amount;localStorage.loan_apr = apr;localStorage.loan_years = years;localStorage.loan_zipcode = zipcode;}}//在文档首次加载时,将会尝试还原输入字段window.onload = function(){//如果浏览器支持本地存储并且上次保存的值是存在的if(window.localStorage && localStorage.loan_amount){document.getElementById("amount").value = localStorage.loan_amount;document.getElementById("apr").value = localStorage.loan_apr;document.getElementById("years").value = localStorage.loan_years;document.getElementById("zipcode").value = localStorage.loan_zipcode;}};/* 将用户的输入发送至服务器端脚本(理论上)将返回一个本地放贷人的链接列表,在这个例子中并没有实现这种查找放贷人的服务但如果该服务存在,该函数会使用它*/function getLenders(amount,apr,years,zipcode){//如果浏览器不支持XMLHttpRequest对象,则退出if(!window.XMLHttpRequest)return;//找到要显示放贷人列表的元素var ad = document.getElementById("lenders");if(!ad)return;      //如果返回值为空,则退出//将用户的输入数据进行URL编码,并作为查询参数附加在URL里var url = "getLenders.php" + "?amt=" + encodeURIComponent(amount) +"&apr=" + encodeURIComponent(apr) +"&yrs=" + encodeURIComponent(years) +"&zip=" + encodeURIComponent(zipcode);//通过XMLHttpRequest对象来提取返回数据var req = new XMLHttpRequest();      //发起一个新的请求req.open("GET",url);                //通过URL发起一个HTTP GET请求req.send(null);                        //不带任何正文发送这个请求/* 在返回数据之前,注册了一个事件处理函数,这个处理函数将会在服务器的响应返回值客户端的时候调用*/req.onreadystatechange = function(){if(req.readyState == 4 && req.status == 200){//如果代码运行到这里,说明我们得到了一个合法且完整的HTTP响应var response = req.responseText;      //HTTP响应是以字符串的形式呈现的var lenders = JSON.parse(response);     //将其解析为JS数组//将数组中的放贷人对象转换为HTML字符串形式var list = "";for(var i = 0;i < lenders.length;i++){list += "<li><a href = '" + lenders[i].url + "'>"+lenders[i].name + "</a>";}//将数据在HTML元素中呈现出来ad.innerHTML = "<ul>" + list + "</ul>";}}}/* 在HTML元素中<canvas>元素中用图表展示月度贷款余额,利息和资产收益如果不传入参数的话,则清空之前的图表数据*/function chart(principal,interest,monthly,payments){var graph = document.getElementById("graph");        //得到<canvas>标签graph.width = graph.width;     //清除并重置画布//如果不传入参数,或者浏览器不支持画布,则直接返回if(arguments.length == 0 || !graph.getContext)return;//获得画布元素的'context'对象,这个对象定义了一组绘画APIvar g = graph.getContext("2d");      //所有的绘画操作都将基于这个对象var width = graph.width,height = graph.height;       //获得画布大小//这里的函数作用是将付款数字和美元数据转换为像素function paymentToX(n){return n * width / payments;}function amountToY(a){return height - (a * height / (monthly * payments * 1.05));}//付款数据是一条从(0,0)到(payments,monthly*payments)的直线g.moveTo(paymentToX(0),amountToY(0));        //从左下方开始g.lineTo(paymentToX(payments),amountToY(monthly * payments));       //绘至右上方g.lineTo(paymentToX(payments),amountToY(0)); //再至右下方 g.closePath();      //将结尾连接至开头g.fillStyle = "#f88";      g.fill();       //填充矩形g.font = "bold 12px sans-serif";       g.fillText("Total Interest Payments",20,20);      //将文字绘制到图例中//很多资产数据并不是线性的,很难将其反映至图表中var equity = 0;g.beginPath();       //开始绘制新图形g.moveTo(paymentToX(0),amountToY(0));      //从左下方开始for(var p = 1;p <= payments;p++){//计算出每一笔赔付的利息var thisMonthsInterest = (principal - equity) * interest;equity += (monthly - thisMonthsInterest);      //得到资产额g.lineTo(paymentToX(p),amountToY(equity));       //将数据绘制到画布上}g.lineTo(paymentToX(payments),amountToY(0));        //将数据线绘制至x轴g.closePath();       //将线条结尾连接至线条开头g.fillStyle = "green";g.fill();        //曲线之下的部分均填充g.fillText("Total Equity",20,35);//再次循环,余额数据显示为黑色粗线条var bal = principal;g.beginPath();g.moveTo(paymentToX(0),amountToY(bal));for(var p = 1;p <= payments;p++){var thisMonthsInterest = bal * interest;bal -= (monthly - thisMonthsInterest);     //得到资产额g.lineTo(paymentToX(p),amountToY(bal));      //将直线连接至某点}g.lineWidth = 3;        //将直线宽度加粗g.stroke();        //绘制余额的曲线g.fillStyle = "black";g.fillText("Loan Balance",20,50);//将年度数据在x轴做标记g.textAlign = "center";var y = amountToY(0);      //Y坐标设置为0for(var year = 1;year * 12 <= payments;year++){//遍历每年var x = paymentToX(year * 12);        //计算标记位置g.fillRect(x - 0.5,y - 3,1,3);      //开始绘制标记if(year == 1)g.fillText("Year",x,y - 5);        //在坐标轴做标记if(year % 5 == 0 && year * 12 !== payments)        //每五年的数据g.fillText(String(year),x,y - 5);}//将赔付数额标记在右边界g.textAlign = "right";g.textBaseline = "middle";var ticks = [monthly * payments,principal];       //我们将要用到的两个点var rightEdge = paymentToX(payments);      //设置X坐标for(var i = 0;i < ticks.length;i++){       //对每两个点做循环var y = amountToY(ticks[i]);     //计算每个标记的Y坐标g.fillRect(rightEdge - 3,y - 0.5,3,1);      //绘制标记g.fillText(String(ticks[i].toFixed(0)),rightEdge - 5,y);      //绘制文本}}</script>

总结

完结:以上就是贷款计算器部分功能点的实现,囊括的知识点较多,如果文中的部分内容讲的不够透彻可以自行到网上查阅相关资料进行整合,最后,感谢各位能看到此处,有什么好的建议希望各位大佬不吝赐教,谢谢各位。

用JavaScript制作一个贷款计算器(注:附带详细注释)相关推荐

  1. 【web前端特效源码】使用HTML5+CSS3+JavaScript制作一个扁平化风格css螃蟹图形~~适合初学者~超简单~ |前端开发|IT软件

    b站视频演示效果: [web前端特效源码]使用HTML5+CSS3+JavaScript制作一个扁平化风格css螃蟹图形~~适合初学者~超简单~ |前端开发|IT软件 效果图: 完整代码: <! ...

  2. 【web前端特效源码】使用HTML5+CSS3+JavaScript制作一个电风扇动画效果~适合初学者~超简单~ |前端开发|IT软件

    b站视频演示效果: [web前端特效源码]使用HTML5+CSS3+JavaScript制作一个电风扇动画效果~适合初学者~超简单~ |前端开发|IT软件 效果图: 完整代码: <!DOCTYP ...

  3. 【web前端特效源码】使用HTML5+CSS3+JavaScript制作一个可拖动的拼图游戏动画效果~适合初学者~超简单~ |it前端开发

    b站视频演示效果: [web前端特效源码]使用HTML5+CSS3+JavaScript制作一个可拖动的拼图游戏动画效果~适合初学者~超简单~ |前端开发|IT软件 效果图: 完整代码: <!D ...

  4. 【web前端特效源码】使用HTML5+CSS3+JavaScript制作一个影子~~适合初学者~超简单~ |前端开发|IT软件

    b站视频演示效果: [web前端特效源码]使用HTML5+CSS3+JavaScript制作一个影子特效~~适合初学者~超简单~ |前端开发|IT软件 效果图: 完整代码: <!DOCTYPE ...

  5. 【前端代码实例】使用HTML5+CSS3+JavaScript制作一个响应式的后台管理系统~带侧边导航栏仪表盘功能

    bilibili在线视频演示地址: [前端代码实例]使用HTML5+CSS3+JavaScript制作一个响应式的后台管理系统~带侧边导航栏仪表盘功能 效果图: 完整代码: <!DOCTYPE ...

  6. 【web前端特效源码】使用HTML5+CSS3+JavaScript制作一个果冻导航标签栏图标按钮效果~~适合初学者~超简单~ |前端开发|IT软件

    b站视频演示效果: [web前端特效源码]使用HTML5+CSS3+JavaScript制作一个果冻导航标签栏图标按钮效果~~适合初学者~超简单~ |前端开发|IT软件 效果图: 完整代码: < ...

  7. 用html制作一个音乐排行榜,使用原生JavaScript制作一个漂亮的音乐播放器

    简单介绍 起初在简书上发现了这篇博客--[html.css.jq]制作一个简洁的音乐播放器.这是一个用jQuery库实现的音乐播放器,界面简约大气. 我在这个基础上,反其道而行,使用原生JavaScr ...

  8. 【web前端特效源码】使用HTML5+CSS3+JavaScript制作一个复古手机键盘(带声音)的动画效果~~适合初学者~超简单~

    b站视频演示效果: [web前端特效源码]使用HTML5+CSS3制作一个复古手机键盘(带声音)的动画效果~~适合初学者~超简单~ |前端开发|IT软件 效果图: 完整代码: <!DOCTYPE ...

  9. 如何用HTML和css实现简单的手风琴菜单效果,附带详细注释

    超完整的代码+详细注释,适合给小白做的简单的手风琴菜单实例 代码: <!DOCTYPE html> <html lang="en"><head> ...

  10. html制作简易计算机,用JavaScript制作一个简易计算器

    制作出来是一个五行三列的表格,第一行是标题简易计算器,第二行是第一个数,第三行是第二个数,第四行是计算机结果,第五行是说明步骤,第三列是加减乘除四种运算方法. 简易计算器 table{ border: ...

最新文章

  1. Vue打包之后会出现.map文件用处
  2. 24 年前的 IE 仍能在 Win10中运行,这无敌兼容性与你的代码比比?
  3. 全网最新 Skywalking 6.1.0部署进k8s 包含springcloud测试用例
  4. oracle设置导出权限,Oracle 创建 删除 用户 导出 导入 分配权限
  5. Kotlin 继续助力 Android 开发,并计划涉足更多领域
  6. 老万的java技术书单:你还在吃快餐吗?
  7. 一个函数中写多少行代码比较合适呢?
  8. ODBC连接达梦数据库配置
  9. 对人工智能的初步认识
  10. Python3 __dict__与dir()区别,对象中私有属性的访问
  11. So Who's Counting? by Erin McHugh and Emily Luchetti
  12. 新冠肺炎的诊断与临床症状
  13. Unity+Vuforia实现AR图片识别应用
  14. win10 UWP 你写我读
  15. C#基础语法————变量
  16. linux shell脚本 字符串、整数、小数判断
  17. python的实验报告大一心理_Python程序设计实验报告: 实验六
  18. sqlite3错误原因
  19. 高可用服务设计之二:Rate limiting 限流与降级
  20. QT--HTTP图片下载器

热门文章

  1. 暴力猴简单脚本 - 去除右键菜单、文本选择限制
  2. swiper实现移动端导航和内容板块的联动
  3. 【图像识别】基于ORL数据库的PCA人脸识别系统matlab源码
  4. 富士施乐m115b怎么连接电脑_富士施乐 Fuji Xerox DocuPrint M118w/M118z打印机无线连接设置详解...
  5. 91卫图助手下载器永久免费啦!!
  6. c语言 鼠标宏,鼠标宏设置软件下载 Mini Mouse Macro(鼠标宏设置工具) v7.2.0.0 免费安装版 下载-脚本之家...
  7. 博科BROCADE交换机开启snmp服务
  8. svn插件Subclipse
  9. linux eclipse svn插件安装,Ubuntu16.04 Eclipse 安装 SVN 插件 subclipse 时 JavaHL 报错解决...
  10. CactiEZ V10.1安装及配置