JavaScript权威指南----一个JavaScript贷款计算器
废话不多说上例子代码:
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>JavaScript Loan Calculator</title>
- <style>
- .output{font-weight: bold;}
- #payment{text-decoration: underline;}
- #graph{border: 1px solid black;}
- th, td{vertical-align: top;}
- </style>
- </head>
- <body>
- <table>
- <tr>
- <th>Enter Loan Data:</th>
- <td></td>
- <th>Loan Balance,Cumulative Equity,and Interest Payments</th>
- </tr>
- <tr>
- <td>Amount of the loan($):</td>
- <td><input id="amount" οnchange="calculate();"/></td>
- <!--数量-->
- <td rowspan="8"><canvas id="graph" width="400" height="250"></canvas></td>
- <!--图表-->
- </tr>
- <tr>
- <td>Annual interest(%):</td>
- <td><input id="apr" οnchange="calculate();" /></td>
- <!--年百分利率-->
- </tr>
- <tr>
- <td>Repayment period (years):</td>
- <td><input id="years" οnchange="calculate();" /></td>
- </tr>
- <tr>
- <td>Zipcode (to find lenders):</td>
- <td><input id="zipcode" οnchange="calculate();" /></td>
- <!--邮政编码-->
- </tr>
- <tr>
- <td>Approximate Payments:</td>
- <td><button id="years" onclick="calculate();">Calculate</button></td>
- <!--计算-->
- </tr>
- <tr>
- <td>Monthly payment:</td>
- <td>$<span class="output" id="payment"></span></td>
- <!--付款-->
- </tr>
- <tr>
- <td>Total interest:</td>
- <td>$<span class="output" id="total"></span></td>
- <!--全部的-->
- </tr>
- <tr>
- <td>Total payment:</td>
- <td>$<span class="output" id="totalinterest"></span></td>
- <!--总利息-->
- </tr>
- <tr>
- <th>Spinsors:</th>
- <td colspan="2">
- Apply for your loan with one of these fine lenders:
- <div id="lenders"></div>
- <!--贷款人-->
- </td>
- </tr>
- </table>
- <script>
- //"use strict";
- 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);
- //如果结果没有超过js能表示的数字范围,且用户的输入也正确
- //这里所展示的结果就是合法的
- if(isFinite(monthly)){
- //将数字填充到输出字段的位置,四舍五入到小数点后两位数字
- payment.innerHTML = monthly.toFixed(2);
- total.innerHTML = ((monthly*payments)-principal).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();
- }
- }
- 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.οnlοad=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" + encodeURLComponent(amount)+
- "?apr" + encodeURLComponent(apr)+
- "?yrs" + encodeURLComponent(years)+
- "?zip" + encodeURLComponent(zipcode);
- //用XMLHttpRequest对象来提取返回数据
- var req = new XMLHttpRequest();//发送一个新的请求
- req.open("GET",url);//通过url发起一个http get请求
- req.send(null);//不带任何正文发送这个请求
- //在返回数据之前,注册一个事件处理函数,这个处理函数将会在服务器的的响应返回至客户端的时候调用
- //这个异步边城模型在客户端js中是非常常见的
- 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></li>"
- }
- //将数据在HTML中呈现出来
- ad.innerHTML = "<ul>"+list+"</ul>";
- }
- }
- }
- //在HTML<canvas>元素中用图表展示月度贷款余额,利息和资产情况
- //如果不传参就清空之前的图表
- function chart(principal,interest,monthly,payments){
- var graph = document.getElementById("graph");
- graph.width = graph.width;//用一种巧妙的手法清除并重置画布
- //如果不传入参数,或者浏览器不支持画布,则直接返回。
- if(arguments.length == 0 || !graph.getContext)return;
- //获得画布元素『context』对象,这个对象定义了一组绘画API
- var 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));
- 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);
- for(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);
- for(var i=0;i<ticks.length;i++){
- var y = amountToY(ticks[i]);
- g.fillRect(rightEdge-3,y-0.5,3,1);
- g.fillText(String(ticks[i].toFixed(0)),rightEdge-5,y);
- }
- }
- </script>
- </body>
- </html>
这边例子有个我感觉错误的地方:
- <tr>
- <td>Approximate Payments:</td>
- <td><button id="years" onchange="calculate();">Calculate</button></td>
- <!--计算-->
- </tr>
这里的onchange是无法触发这个计算函数,需要改成onclick函数;
JavaScript权威指南----一个JavaScript贷款计算器的更多相关文章
- javascript权威指南笔记--javascript语言核心(二)
1.函数作用域:在函数内声明的所有变量在函数体内始终是可见的.这意味着在变量声明之前甚至已经可用. *“声明提前”:javascript函数里声明的所有变量(但不涉及赋值)都被提前至函数的顶部. fu ...
- javascript权威指南笔记--javascript语言核心(四)
对象: 通过引用(而非值)来操作对象: var obj = {"x":1,"y":2}; var copyObj = obj; copyObj.x = 5; c ...
- javascript权威指南笔记--javascript语言核心(三)
1.var用来声明一个或多个变量.全局变量是全局对象的属性,它无法通过delete删除. 如果var语句中的变量没有指定初始化表达式,那么这个变量的初始值为undefined. 变量声明语句会被提前到 ...
- javascript权威指南笔记--javascript语言核心(一)
1.javascript的数据类型分为两类:原始类型和对象类型. 原始类型包括字符串.数字.布尔值.null.undefined. 对象是属性的集合,每个对象都由“名/值”对构成.数组和函数是特殊的对 ...
- javascript权威指南笔记--javascript语言核心(六)
通过ECMAScript 3创建的属性都是可写的.可枚举的.可配置的. 在ECMAScript 5中,数据属性的4个特性分别是它的值.可写性.可枚举性.可配置性.存取器属性的特性是读取.写入.可枚举性 ...
- javascript权威指南笔记--javascript语言核心(五)--getter和setter属性
getter和setter属性: var p = { x:1.0, y:1.0, get r(){ return Math.sqrt(this.x*this.x + this.y * this.y); ...
- JavaScript权威指南 - 函数
函数本身就是一段JavaScript代码,定义一次但可能被调用任意次.如果函数挂载在一个对象上,作为对象的一个属性,通常这种函数被称作对象的方法.用于初始化一个新创建的对象的函数被称作构造函数. 相对 ...
- JavaScript权威指南 - 对象
JavaScript对象可以看作是属性的无序集合,每个属性就是一个键值对,可增可删. JavaScript中的所有事物都是对象:字符串.数字.数组.日期,等等. JavaScript对象除了可以保持自 ...
- JavaScript权威指南 - 数组
JavaScript数组是一种特殊类型的对象. JavaScript数组元素可以为任意类型,最大容纳232-1个元素. JavaScript数组是动态的,有新元素添加时,自动更新length属性. J ...
随机推荐
- 纯CSS焦点轮播效果-功能可扩展
个人博客: http://mcchen.club 纯CSS3实现模拟焦点轮播效果,支持JQ等扩展各项功能.废话少说,直接贴代码. <!DOCTYPE html> <html> ...
- e课表项目第二次冲刺周期第三天
昨天干了什么? 昨天和我们组的组员商量,确定了第二个界面的框架内容,即内容的输入和完成按钮,然后通过在网上搜索图片资源,然后我们利用ps软件,将图片通通设置了大小,进行了裁剪,最后为我们所利用,实现第 ...
- Hackers' Crackdown UVA - 11825
Miracle Corporations has a number of system services running in a distributed computer system which ...
- 并发新构件之DelayQueue:延时队列
DelayQueue:延时队列,首先是一个队列,所以可以持有对象,但是仅限于实现了Delayed接口的对象.重写getDelay()和compareTo()(因为要比较)方法: 通俗来讲:延时队列的就 ...
- winsock完成端口套接字重用注意事项
刚申请到博客,第一篇随笔(๑•̀ㅂ•́)و✧ 关于DisconnectEx的一个问题,目前主要发现在windows10中出现了这个问题,winserver2008 win7都没有这个问题. 被Disc ...
- python常用算法(5)——树,二叉树与AVL树
1,树 树是一种非常重要的非线性数据结构,直观的看,它是数据元素(在树中称为节点)按分支关系组织起来的结构,很像自然界中树那样.树结构在客观世界中广泛存在,如人类社会的族谱和各种社会组织机构都可用树形 ...
- Vtable内存布局分析
vtale 内存布局分析 虚函数表指针与虚函数表布局 考虑如下的 class: class A { public: int a; virtual void f1() {} virtual void f ...
- Hydra爆破神器使用
参数详解: -R 根据上一次进度继续破解-S 使用SSL协议连接-s 指定端口-l 指定用户名-L 指定用户名字典(文件)-p 指定密码破解-P 指定密码字典(文件)-e 空密码探测和指定用户密码探测 ...
- shark恒破解笔记1-壳内寻找注册码
记录学习shark恒大教程的学习记录 壳内寻找注册码 OD打开 明显有壳 F9先运行程序 2.Ctrl+G输入401000到解码段,如果出现db ** 说明已经解码过,脱离了程序本身的壳 鼠标右键-& ...
- Unity 登录白屏或者黑屏
如果有一天,突然,你的Unity抽风了,登录界面白屏或者黑屏,不要急着重装.我重装了3次,第四次我再也忍不住了,终于出手了. 找到 C:\Users\hasee\AppData\Roaming\Uni ...