JavaScript权威指南----一个JavaScript贷款计算器

废话不多说上例子代码:

 

  1 <!DOCTYPE html>
  2 <html>
  3  
  4     <head>
  5         <meta charset="UTF-8">
  6         <title>JavaScript Loan Calculator</title>
  7         <style>
  8             .output{font-weight: bold;}
  9             #payment{text-decoration: underline;}
 10             #graph{border: 1px solid black;}
 11             th, td{vertical-align: top;}
 12  
 13         </style>
 14     </head>
 15  
 16     <body>
 17         <table>
 18             <tr>
 19                 <th>Enter Loan Data:</th>
 20                 <td></td>
 21                 <th>Loan Balance,Cumulative Equity,and Interest Payments</th>
 22             </tr>
 23             <tr>
 24                 <td>Amount of the loan($):</td>
 25                 <td><input id="amount" οnchange="calculate();"/></td>
 26                 <!--数量-->
 27                 <td rowspan="8"><canvas id="graph" width="400" height="250"></canvas></td>
 28                 <!--图表-->
 29             </tr>
 30             <tr>
 31                 <td>Annual interest(%):</td>
 32                 <td><input id="apr" οnchange="calculate();" /></td>
 33                 <!--年百分利率-->
 34             </tr>
 35             <tr>
 36                 <td>Repayment period (years):</td>
 37                 <td><input id="years" οnchange="calculate();" /></td>
 38             </tr>
 39             <tr>
 40                 <td>Zipcode (to find lenders):</td>
 41                 <td><input id="zipcode" οnchange="calculate();" /></td>
 42                 <!--邮政编码-->
 43             </tr>
 44             <tr>
 45                 <td>Approximate Payments:</td>
 46                 <td><button id="years" onclick="calculate();">Calculate</button></td>
 47                 <!--计算-->
 48             </tr>
 49             <tr>
 50                 <td>Monthly payment:</td>
 51                 <td>$<span class="output" id="payment"></span></td>
 52                 <!--付款-->
 53             </tr>
 54             <tr>
 55                 <td>Total interest:</td>
 56                 <td>$<span class="output" id="total"></span></td>
 57                 <!--全部的-->
 58             </tr>
 59             <tr>
 60                 <td>Total payment:</td>
 61                 <td>$<span class="output" id="totalinterest"></span></td>
 62                 <!--总利息-->
 63             </tr>
 64             <tr>
 65                 <th>Spinsors:</th>
 66                 <td colspan="2">
 67                     Apply for your loan with one of these fine lenders:
 68                     <div id="lenders"></div>
 69                     <!--贷款人-->
 70                 </td>
 71             </tr>
 72         </table>
 73         <script>
 74             //"use strict";
 75             function calculate(){
 76                 //查找文档中用于输入输出的元素
 77                 var amount = document.getElementById("amount");
 78                 var apr = document.getElementById("apr");
 79                 var years = document.getElementById("years");
 80                 var zipcode = document.getElementById("zipcode");
 81                 var payment = document.getElementById("payment");
 82                 var total = document.getElementById("total");
 83                 var totalinterest = document.getElementById("totalinterest");
 84                 
 85                 //假如所有的输入都是合法的,将从input中获取输入数据
 86                 //将百分比格式转换成小数格式,并从年利率转化成月利率
 87                 //将年度赔付装换成月度赔付
 88                 var principal = parseFloat(amount.value);
 89                 var interest = parseFloat(apr.value)/100/12;
 90                 var payments = parseFloat(years.value)*12;
 91                 
 92                 //现在计算月度赔付的数据
 93                 var x =Math.pow(1+interest,payments);//Math.pow()进行幂次运算
 94                 var monthly = (principal*x*interest)/(x-1);
 95                 
 96                 //如果结果没有超过js能表示的数字范围,且用户的输入也正确
 97                 //这里所展示的结果就是合法的
 98                 if(isFinite(monthly)){
 99                     //将数字填充到输出字段的位置,四舍五入到小数点后两位数字
100                     payment.innerHTML = monthly.toFixed(2);
101                     total.innerHTML = ((monthly*payments)-principal).toFixed(2);
102                     totalinterest.innerHTML=((monthly*payments)-principal).toFixed(2);
103                     
104                     //将用户输入的数据保存下来,这样下次访问时候也能取到数据
105                     save(amount.value,apr.value,years.value,zipcode.value);
106                     
107                     //找到并展示放贷人,但忽略网络错误
108                     try{
109                         //捕获这段代码抛出的所有异常
110                         getLenders(amount.value,apr.value,years.value,zipcode.value);
111                     }
112                     //忽略这些异常
113                     catch(e){}
114                     
115                     //最后,用图表展示贷款余额,利息和资产收益
116                     chart(principal,interest,monthly,payments);
117                 }else{
118                     payment.innerHTML="";
119                     total.innerHTML="";
120                     totalinterest.innerHTML="";
121                     chart();
122                 }
123             }
124             
125             function save(amount,apr,years,zipcode){
126                 if(window.localStorage){//只有在浏览器支持的时候才支持这里的代码
127                     localStorage.loan_amount = amount;
128                     localStorage.loan_apr = apr;
129                     localStorage.loan_years = years;
130                     localStorage.loan_zipcode = zipcode;
131                 }
132             }
133             
134             //文档首次加载的时候,将会尝试还原输入字段
135             window.οnlοad=function(){
136                 //如果浏览器支持本地存储并且上次保存的值是存在的
137                 if(window.localStorage && localStorage.loan_amount){
138                     document.getElementById("amount").value = localStorage.loan_amount;
139                     document.getElementById("apr").value = localStorage.loan_apr;
140                     document.getElementById("years").value = localStorage.loan_years;
141                     document.getElementById("zipcode").value = localStorage.loan_zipcode;
142                 }
143             }
144             
145             //将用户的输入发送到服务器端脚本返回一个本地放贷人的连接列表,在这个例子中并没有是现在这种查找放贷人的服务
146             //但如果该服务存在,该函数会使用它
147             function getLenders(amount,apr,years,zipcode){
148                 //如果浏览器不支持XMLHttpRequest对象,则退出
149                 if (!window.XMLHttpRequest)return;
150                 
151                 //找到要显示放贷人列表的元素
152                 var ad=document.getElementById("lenders");
153                 if(!ad)return;//如果返回为空则退出
154                 
155                 //将用户的输入数据进行url编码,并作为查询参数附加在URL里
156                 var url = "getLenders.php"+
157                 "?amt" + encodeURLComponent(amount)+
158                 "?apr" + encodeURLComponent(apr)+
159                 "?yrs" + encodeURLComponent(years)+
160                 "?zip" + encodeURLComponent(zipcode);
161                 
162                 //用XMLHttpRequest对象来提取返回数据
163                 var req = new XMLHttpRequest();//发送一个新的请求
164                 req.open("GET",url);//通过url发起一个http get请求
165                 req.send(null);//不带任何正文发送这个请求
166                 
167                 //在返回数据之前,注册一个事件处理函数,这个处理函数将会在服务器的的响应返回至客户端的时候调用
168                 //这个异步边城模型在客户端js中是非常常见的
169                 req.onreadystatechange = function(){
170                     if(req.readyState == 4 && req.status == 200){
171                         //如果代码运行到这里,说明我们得到了一个合法且完整的http响应
172                         var response = req.responseText;//http响应是以字符串的形式呈现的
173                         var lenders = JSON.parse(response);//将其解析为js数组
174                         
175                         //将数组中的放贷人对象转换成HTML字符串的形式
176                         var list="";
177                         for(var i=0;i<lenders.length;i++){
178                             list += "<li><a href='"+ lenders[i].url +"'>"+lenders[i].name+"</a></li>"
179                         }
180                         
181                         //将数据在HTML中呈现出来
182                         ad.innerHTML = "<ul>"+list+"</ul>";
183                     }
184                 }
185                 
186             }
187             
188             //在HTML<canvas>元素中用图表展示月度贷款余额,利息和资产情况    
189             //如果不传参就清空之前的图表
190             function chart(principal,interest,monthly,payments){
191                 var graph = document.getElementById("graph");
192                 graph.width = graph.width;//用一种巧妙的手法清除并重置画布
193                 
194                 //如果不传入参数,或者浏览器不支持画布,则直接返回。
195                 if(arguments.length == 0 || !graph.getContext)return;
196                 
197                 //获得画布元素『context』对象,这个对象定义了一组绘画API
198                 var g = graph.getContext("2d");
199                 var width = graph.width,height = graph.height; 
200                 
201                 //这里的函数的作用是将付款数字和美元数字转换成像素
202                 function paymentToX(n){
203                     return n*width/payments;
204                 }
205                 function amountToY(a){
206                     return height - (a*height/(monthly*payments*1.05));
207                 }
208                 
209                 //付款数据是一条从(0,0)到(payments,monthly*payments)的直线
210                 g.moveTo(paymentToX(0),amountToY(0));
211                 g.lineTo(paymentToX(payments),amountToY(monthly*payments));
212                 g.lineTo(paymentToX(payments),amountToY(0));
213                 g.closePath();
214                 g.fillStyle = "#f88";
215                 g.fill();
216                 g.font = "bold 12px sans-serif";
217                 g.fillText("Total Interest Payments",20,20);
218                 
219                 //很多资产数据并不是线性的,很难将其反映到图标中
220                 var equity = 0;
221                 g.beginPath();
222                 g.moveTo(paymentToX(0),amountToY(0));
223                 for(var p=1;p<=payments;p++){
224                     //计算出每一笔赔付的利息
225                     var thisMonthsINterest = (principal - equity)*interest;
226                     equity += (monthly -thisMonthsInterest);
227                     g.lineTo(paymentToX(p),amountToY(equity));
228                 }
229                 g.lineTo(paymentToX(payments),amountToY(0));
230                 g.closePath();
231                 g.fillStyle = "green";
232                 g.fill();
233                 g.fillText("Total Equity",20,35);
234                 
235                 //再次循环,余额数据显示为黑色粗线条
236                 var bal = principal;
237                 g.beginPath();
238                 g.moveTo(paymentToX(0),amountToY(bal));
239                 for(var p=1;p<=payments;p++){
240                     var thisMonthsInterest = bal*interest;
241                     bal-=(monthly - thisMonthsInterest);
242                      g.lineTo(paymentToX(p),amountToY(bal));
243                 }
244                 
245                 g.lineWidth = 3;
246                 g.stroke();
247                 g.fillStyle ="black";
248                 g.fillText("Loan Balance",20,50);
249                 
250                 //将年度数据在X轴做标记
251                 g.textAlign = "center";
252                 var y = amountToY(0);
253                 for(var year = 1;year*12<=payments;year++){
254                     var x=paymentToX(year*12);
255                     g.fillRect(x-0.5,y-3,1,3);
256                     if(year == 1) g.fillText("Year",x,y-5);
257                     if(year %5 ==0 && year*12 !== payments)
258                     g.fillText(String(year),x,y-5);
259                 }
260                 
261                 //将赔付数额标记在右边界
262                 g.textAlign = "right";
263                 g.textBaseline ="middle";
264                 var ticks = [monthly * payments,principal];
265                 var rightEdge = paymentToX(payments);
266                 for(var i=0;i<ticks.length;i++){
267                     var y = amountToY(ticks[i]);
268                     g.fillRect(rightEdge-3,y-0.5,3,1);
269                     g.fillText(String(ticks[i].toFixed(0)),rightEdge-5,y);
270                 }
271             }
272         </script>
273     </body>
274  
275 </html>
View Code

 

 

这边例子有个我感觉错误的地方:

1 <tr>
2     <td>Approximate Payments:</td>
3     <td><button id="years" onchange="calculate();">Calculate</button></td>
4     <!--计算-->
5 </tr>
View Code

 

这里的onchange是无法触发这个计算函数,需要改成onclick函数;

 

 

 

 

 

 

posted @ 2019-11-11 17:46  白羽流光  阅读(437)  评论(1编辑  收藏  举报