废话不多说上例子代码:

 <!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贷款计算器的更多相关文章

  1. javascript权威指南笔记--javascript语言核心(二)

    1.函数作用域:在函数内声明的所有变量在函数体内始终是可见的.这意味着在变量声明之前甚至已经可用. *“声明提前”:javascript函数里声明的所有变量(但不涉及赋值)都被提前至函数的顶部. fu ...

  2. javascript权威指南笔记--javascript语言核心(四)

    对象: 通过引用(而非值)来操作对象: var obj = {"x":1,"y":2}; var copyObj = obj; copyObj.x = 5; c ...

  3. javascript权威指南笔记--javascript语言核心(三)

    1.var用来声明一个或多个变量.全局变量是全局对象的属性,它无法通过delete删除. 如果var语句中的变量没有指定初始化表达式,那么这个变量的初始值为undefined. 变量声明语句会被提前到 ...

  4. javascript权威指南笔记--javascript语言核心(一)

    1.javascript的数据类型分为两类:原始类型和对象类型. 原始类型包括字符串.数字.布尔值.null.undefined. 对象是属性的集合,每个对象都由“名/值”对构成.数组和函数是特殊的对 ...

  5. javascript权威指南笔记--javascript语言核心(六)

    通过ECMAScript 3创建的属性都是可写的.可枚举的.可配置的. 在ECMAScript 5中,数据属性的4个特性分别是它的值.可写性.可枚举性.可配置性.存取器属性的特性是读取.写入.可枚举性 ...

  6. 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); ...

  7. JavaScript权威指南 - 函数

    函数本身就是一段JavaScript代码,定义一次但可能被调用任意次.如果函数挂载在一个对象上,作为对象的一个属性,通常这种函数被称作对象的方法.用于初始化一个新创建的对象的函数被称作构造函数. 相对 ...

  8. JavaScript权威指南 - 对象

    JavaScript对象可以看作是属性的无序集合,每个属性就是一个键值对,可增可删. JavaScript中的所有事物都是对象:字符串.数字.数组.日期,等等. JavaScript对象除了可以保持自 ...

  9. JavaScript权威指南 - 数组

    JavaScript数组是一种特殊类型的对象. JavaScript数组元素可以为任意类型,最大容纳232-1个元素. JavaScript数组是动态的,有新元素添加时,自动更新length属性. J ...

随机推荐

  1. 安装Office Visio 提示Office 16 Click-to-Run Extensibility Component

    今天在安装 Office Visio 2016 时,点击安装程序,出现以下错误:   出现这个问题的原因就是你的电脑以前安装过32位的office,卸载时,注册表没有清理干净. 解决方案: 在win1 ...

  2. git远程分支不显示问题解决

    因为项目太大,然后直接git clone拉不下来代码 会报error: RPC failed; HTTP 504 curl 22 The requested URL returned error: 5 ...

  3. BZOJ [Scoi2015]情报传递

    Description 奈特公司是一个巨大的情报公司,它有着庞大的情报网络.情报网络中共有n名情报员.每名情报员口J-能有 若T名(可能没有)下线,除1名大头日外其余n-1名情报员有且仅有1名上线.奈 ...

  4. 最强最全的Java后端知识体系

    目录 最全的Java后端知识体系 Java基础 算法和数据结构 Spring相关 数据库相关 方法论 工具清单 文档 @(最强最全的Java后端知识体系) 最全的Java后端知识体系 最全的Java后 ...

  5. 腾讯新闻抢金达人活动node同构直出渲染方案的总结

    我们的业务在展开的过程中,前端渲染的模式主要经历了三个阶段:服务端渲染.前端渲染和目前的同构直出渲染方案. 服务端渲染的主要特点是前后端没有分离,前端写完页面样式和结构后,再将页面交给后端套数据,最后 ...

  6. Python3_基础

    目录 数据类型 变量 数据类型的转换 算术操作符 输入 字符串常用方法 数据类型 我们先来看看三种常见的数据类型 字符串 str 在Python中,字符串一般都用引号引起来,不管是用单引号还是双引号都 ...

  7. Web前端助手-功能丰富的Chrome插件

    整合优秀的前端实用工具.免费,可配置的强大工具集 示例 安装 github仓库: https://github.com/zxlie/FeHelper 官网地址:https://www.baidufe. ...

  8. 实验吧之【who are you?】(时间盲注)补充

    第二种方法 使用brup进行盲注  也是一个道理 不多贴了 这里提一下  burp怎么判断超时 Options->Connections->Tiimeouts->Normal这一空 ...

  9. find命令面试题

    注意 (1)建议先创建快照 (2)有可能存在命令正确,但是查找不到文件的情况,是因为不存在相关条件的文件 (3)如果存在命令正确,但是查找不到文件的情况,则先创建相关的文件.目录.用户.组,设置好对应 ...

  10. 3. SOFAJRaft源码分析— 是如何进行选举的?

    开篇 在上一篇文章当中,我们讲解了NodeImpl在init方法里面会初始化话的动作,选举也是在这个方法里面进行的,这篇文章来从这个方法里详细讲一下选举的过程. 由于我这里介绍的是如何实现的,所以请大 ...