<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>基於 Js 實現 的貸款計算器</title>
<style>
.output {font-weight:bold;}
#payment {text-decoration: underline;}
#graph {border: solid black 1px;}
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" 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 (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>Approximate Payments:</th>
<td><button onclick = "calculate()">Calculate</button></td>
</tr>
<tr>
<td>Monthly paymennt:</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>
<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("total");
var totalinterest = document.getElementById("totalinterest");
//假設all輸入都是合法d,將從 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);
var monthly = (principal * x * interest) / (x - 1);
//如果結果沒超過Js 能標識的數字範圍,且輸入正確,那麼展示結果合法
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 {
//計算結果不是數字或者是 inf ,意味著輸入數據是非法、不完整
//清空之前的輸入數據
payment.innerHTML = "";
total.innerHTML = ""
totalinterest.innerHTML = "";
chart();
}
}
//將用戶的輸入保存到 localStorage 對象的屬性中
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) {
//如果瀏覽器不支持XMLHttpReques對象,則退出
if (!window.XMLHttpRequest) return;
//找到要顯示放貸人列表的元素
var ad = document.getElementById("lenders");
if (!ad) return; //如空,則退
//將輸入數據進行URL編碼, 並作為查詢參數附加於URL裏
var url = "getLenders.php" + //處理數據的URL地址
"?amt=" + encodeURIComponent(amount) +
"&apr" + encodeURIComponent(apr) +
"&yrs=" + encodeURIComponent(years) +
"&zip" + encodeURIComponent(zipcode);
//通過XMLHttpRequest對象來提取返回數據
var req = new XMLHttpRequest();
req.open("GET", url);
req.send(null);
//返回數據之前,註冊一個事件處理函數
//該函數在服務器的響應返回到客戶端的時候
//調用這種異步編程模型在客戶端JS中非常常見
req.onreadystatechange = function() {
if (req.readyState == 4 && req.status == 200) {
//如果代碼走到這裡,我們已經得到一個合法且完整的 http 響應
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>";
}
//將數據在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));
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>
基於 Js 實現 的貸款計算器—犀牛書
最新推荐文章于 2022-01-06 17:45:03 发布