基於 Js 實現 的貸款計算器—犀牛書

12 篇文章 0 订阅
12 篇文章 0 订阅
<!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>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值