<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>贷款计算器</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 Date:</th>
<td></td>
<th>Loan Balance,Cumulative Equity, and Interest Payments</th>
</tr>
<tr>
<td>Amount of the loan ($):</td>
<td><input id = "amount" onchange = "calculate();"/></td>
<td rowspan = "8"><canvas id = "graph" width = "400" height = "250"></canvas></td>
</tr>
<tr>
<td>Annual interest (%):</td>
<td><input id = "apr" onchange = "calculate();"/></td>
</tr>
<tr>
<td>Repayment period (year):</td>
<td><input id = "years" onchange = "calculate();"/></td>
</tr>
<tr>
<td>Zipcode (to find lenders):</td>
<td><input id="zipcode" "calculate();"/></td>
</tr>
<tr>
<th>Approxyimate Payment:</th>
<td><button onclick = "calculate();">Calculate</button></td>
</tr>
<tr>
<td>Monthiy payment:</td>
<td>$<span class = "output" id = "payment" ></span></td>
</tr>
<tr>
<td>Total payment:</td>
<td>$<span class = "output" id = "total"></span></td>
</tr>
<tr>
<td>Total interest:</td>
<td>$<span class = "output" id = "totalinterest" ></span></td>
</tr>
<tr>
<th>Sponsors:</th>
<td colspan="2">Apply for your loan with one of these fine lenders:
<div id="lenders"></div></td>
</tr>
</table>
</body>
<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");
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);
var monthly = (principal * x * interest)/(x - 1);
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(); //不传参数就清除图表
}
}
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){
if(!window.XMLHttpRequest) return;//如果浏览器不支持XMLHttpRequest对象则退出
//查找放贷人的列表的元素
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,true);//通过URL发起http get请求
req.send(null);//不带任何正文发送这个请求
//返回数据之前注册一个事件处理函数,这个处理函数将会在服务器响应返回至客户端的时候调用
//这种异步编程模型在客户端JavaScript中非常常见
req.onreadystatechange = function(){
if(req.readyState == 4 && req.status == 200){
var response = req.responseText;
var lenders = JSON.parse(response);
//将数组中的房贷人对象转换为HTML字符串形式
var list = "";
for(var i = 0; i < lenders.length; i++){
list += "<li><a href = '" + lenders[i].url + "'>" + lenders[i].name + "</a>";
}
//将数据中的房贷对象转换中呈现出来
ad.innerHTML = "<ul>" + list + "</ul>";
}
}
}
function chart( principal, interest, monthly,payments){
var graph = document.getElementById("graph");
graph.width = graph.width;//清除并重置画布
//如果不传参或浏览器不支持画布,则直接返回
if(arguments.length == 0 || !graph.getContext) return;
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));}
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 thisMonthInterest = bal * interest;
bal -= (monthly - thisMonthInterest);
g.lineTo(paymentToX(p),amountToY(bal));
}
g.lineWidth = 3;
g.stroke();
g.fillStyle = "black";
g.fillText("Loan Balance",20,50);
g.textAligh = "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.textAligh = "right";
g.textBaseline = "middle";
var ticks = [monthly * payments,principal];
var rightEdge = paymentToX(payment);
for(var i = 0; i < ticks.lenght; 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>
</html>
效果图:
代码来自书本JavaScript权威指南例