<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>基于JavaScript實現的貸款計算器</title>
<style>
/*這是一個css樣式表:定義看程序輸出的樣式*/
.output {font-weight: bold;}
#payment {text-decoration: underline;}
#graph{border: solid black 1px}
th ,td {
vertical-align: top;
}
</style>
</head>
<body>
<table>
<tr>
<th>
輸入貸款數據:
</th>
<td></td>
<th>貸款余額减拭,累計權益和利息支付</th>
</tr>
<tr>
<td>貸款額($):</td>
<!--onchange 事件會在域的內容改變時發(fā)生抖部。-->
<td><input id="amount" onchange="calculate()"></td>
<!--rowspan 屬性規(guī)定單元格可橫跨的行數。-->
<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>還款期限(年):</td>
<td><input id="years" onchange="calculate()"></td>
</tr>
<tr>
<td>郵編(找到貸方):</td>
<td><input id="zipcode" onchange="calculate()"></td>
</tr>
<tr>
<th>近似付款:</th>
<td>
<button onclick="calculate()">計算</button>
</td>
</tr>
<tr>
<td>每月支付:</td>
<td>$<span class="output" id="payment"></span></td>
</tr>
<tr>
<td>總付款:</td>
<td>$<samp class="output" id="total"></samp></td>
</tr>
<tr>
<td>總利息:</td>
<td>$<span class="output" id="totalinterset"></span></td>
</tr>
<tr>
<td>贊助商:</td>
<td colspan="2">
向這些優(yōu)良貸款人申請貸款:
<div id="lenders"></div>
</td>
</tr>
</table>
<script>
"use strict"; //如果瀏覽器支持的話,則開始ECMAScript5的嚴格模式
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 totalinterset = document.getElementById("totalinterset");
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);
// isFinite() 函數用于檢查其參數是否是無窮大膀斋。
if (isFinite(monthly)) {
//將數據填充至輸出字段的位置磕昼,四舍五入到小數點后兩位數字
payment.innerHTML = monthly.toFixed(2); //toFixed() 方法可把 Number 四舍五入為指定小數位數的數字俺驶。
total.innerHTML = (monthly * payments).toFixed(2);
totalinterset.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 = "";
totalinterset.innerHTML = "";
chart();
}
}
//將用戶的輸入保存至localStorage對象的屬性中
//這些屬性在再次訪問時還會繼續(xù)保持在原位置
//如果你在瀏覽器中按照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;
}
}
//將用戶的輸入發(fā)送至服務器端腳本將返回一個本地放貸人的連接列表,
//但是我們這個例子沒有實現這種查找放貸人的服務
//如果該服務存在剑令,該函數會使用它
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" + //處理數據的URL地址
"?amt=" + encodeURIComponent(amount) + //使用查詢串中的數據
"&apr=" + encodeURIComponent(apr) +
"&yrs=" + encodeURIComponent(years) +
"&zip=" + encodeURIComponent(zipcode);
//通過XMLHttpRequest對象來提取返回數據
var req = new XMLHttpRequest(); //發(fā)起一個新的請求
req.open("GET", url); //通過url發(fā)起一個HTTP GET請求
req.send(null); //不帶任何正文發(fā)送這個請求
//在返回數據之前棚蓄,注冊了一個事件處理函數堕扶,這個處理函數將會在服務器的響應
//返回至客戶端的時候調用,這種異步編程模型在客戶端JavaScript中是非常常見的
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"); //得到<canvas>
graph.width = graph.width; //用一種巧妙的手法清楚并重置畫布
//獲取畫布元素的"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("總利息支付", 20, 20); //將文字回執(zhí)到圖例中
//很多資產數據并不是線性的糊探,很難將其反應至圖表中
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("總資產", 20, 35);
/*文本設置為綠色*/
//再次循環(huán),余額數據顯示為黑色粗體線條
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("貸款余額", 20, 50);
//將年度數據在X軸做標記
g.textAlign = "center"; //文字居中對齊
var y = amountToY(0); //Y坐標設為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("正確", 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, payments];
var rightEde = paymentToX(payments);
for (var i = 0; i < ticks.length; i++) {
var y = amountToY(ticks[i]);
g.fillRect(rightEde - 3, y - 0.5, 3, 1);
g.fillText(String(ticks[i].toFixed(0)), rightEde - 5, y);
}
}
}
</script>
</body>
</html>
基于javascript實現的貸款計算器
?著作權歸作者所有,轉載或內容合作請聯系作者
- 文/潘曉璐 我一進店門儡炼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來妓湘,“玉大人,你說我怎么就攤上這事乌询“裉” “怎么了?”我有些...
- 文/不壞的土叔 我叫張陵楣责,是天一觀的道長竣灌。 經常有香客問我,道長秆麸,這世上最難降的妖魔是什么初嘹? 我笑而不...
- 正文 為了忘掉前任,我火速辦了婚禮沮趣,結果婚禮上屯烦,老公的妹妹穿的比我還像新娘。我一直安慰自己房铭,他們只是感情好驻龟,可當我...
- 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著缸匪,像睡著了一般翁狐。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上凌蔬,一...
- 文/蒼蘭香墨 我猛地睜開眼纺涤,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了抠忘?” 一聲冷哼從身側響起撩炊,我...
- 正文 年R本政府宣布织中,位于F島的核電站,受9級特大地震影響衷戈,放射性物質發(fā)生泄漏狭吼。R本人自食惡果不足惜,卻給世界環(huán)境...
- 文/蒙蒙 一殖妇、第九天 我趴在偏房一處隱蔽的房頂上張望刁笙。 院中可真熱鬧,春花似錦谦趣、人聲如沸疲吸。這莊子的主人今日做“春日...
- 文/蒼蘭香墨 我抬頭看了看天上的太陽摘悴。三九已至,卻和暖如春舰绘,著一層夾襖步出監(jiān)牢的瞬間蹂喻,已是汗流浹背葱椭。 一陣腳步聲響...
推薦閱讀更多精彩內容
- GraphQL是什么逞壁? GraphQL [http://graphql.org/]是Facebook開發(fā)的一個應用...
- 學完本篇文章,你會感覺你很想寫自動點擊方式的外掛了,就是這么爽,這么簡單,鎖屏 點擊 都那么easy. 簡單的測試...