废话不多说上例子代码:

  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>

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

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

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

JavaScript权威指南----一个JavaScript贷款计算器的更多相关文章

  1. javascript权威指南笔记--javascript语言核心(二)

    1.函数作用域:在函数内声明的所有变量在函数体内始终是可见的.这意味着在变量声明之前甚至已经可用. *“声明提前”:javascript函数里声明的所有变量(但不涉及赋值)都被提前至函数的顶部. fu ...

  2. javascript权威指南笔记--javascript语言核心(四)

    对象: 通过引用(而非值)来操作对象: var obj = {"x":1,"y":2}; var copyObj = obj; copyObj.x = 5; c ...

  3. javascript权威指南笔记--javascript语言核心(三)

    1.var用来声明一个或多个变量.全局变量是全局对象的属性,它无法通过delete删除. 如果var语句中的变量没有指定初始化表达式,那么这个变量的初始值为undefined. 变量声明语句会被提前到 ...

  4. javascript权威指南笔记--javascript语言核心(一)

    1.javascript的数据类型分为两类:原始类型和对象类型. 原始类型包括字符串.数字.布尔值.null.undefined. 对象是属性的集合,每个对象都由“名/值”对构成.数组和函数是特殊的对 ...

  5. javascript权威指南笔记--javascript语言核心(六)

    通过ECMAScript 3创建的属性都是可写的.可枚举的.可配置的. 在ECMAScript 5中,数据属性的4个特性分别是它的值.可写性.可枚举性.可配置性.存取器属性的特性是读取.写入.可枚举性 ...

  6. javascript权威指南笔记--javascript语言核心(五)--getter和setter属性

    getter和setter属性: var p = { x:1.0, y:1.0, get r(){ return Math.sqrt(this.x*this.x + this.y * this.y); ...

  7. JavaScript权威指南 - 函数

    函数本身就是一段JavaScript代码,定义一次但可能被调用任意次.如果函数挂载在一个对象上,作为对象的一个属性,通常这种函数被称作对象的方法.用于初始化一个新创建的对象的函数被称作构造函数. 相对 ...

  8. JavaScript权威指南 - 对象

    JavaScript对象可以看作是属性的无序集合,每个属性就是一个键值对,可增可删. JavaScript中的所有事物都是对象:字符串.数字.数组.日期,等等. JavaScript对象除了可以保持自 ...

  9. JavaScript权威指南 - 数组

    JavaScript数组是一种特殊类型的对象. JavaScript数组元素可以为任意类型,最大容纳232-1个元素. JavaScript数组是动态的,有新元素添加时,自动更新length属性. J ...

随机推荐

  1. 纯CSS焦点轮播效果-功能可扩展

    个人博客: http://mcchen.club 纯CSS3实现模拟焦点轮播效果,支持JQ等扩展各项功能.废话少说,直接贴代码. <!DOCTYPE html> <html> ...

  2. e课表项目第二次冲刺周期第三天

    昨天干了什么? 昨天和我们组的组员商量,确定了第二个界面的框架内容,即内容的输入和完成按钮,然后通过在网上搜索图片资源,然后我们利用ps软件,将图片通通设置了大小,进行了裁剪,最后为我们所利用,实现第 ...

  3. Hackers' Crackdown UVA - 11825

    Miracle Corporations has a number of system services running in a distributed computer system which ...

  4. 并发新构件之DelayQueue:延时队列

    DelayQueue:延时队列,首先是一个队列,所以可以持有对象,但是仅限于实现了Delayed接口的对象.重写getDelay()和compareTo()(因为要比较)方法: 通俗来讲:延时队列的就 ...

  5. winsock完成端口套接字重用注意事项

    刚申请到博客,第一篇随笔(๑•̀ㅂ•́)و✧ 关于DisconnectEx的一个问题,目前主要发现在windows10中出现了这个问题,winserver2008 win7都没有这个问题. 被Disc ...

  6. python常用算法(5)——树,二叉树与AVL树

    1,树 树是一种非常重要的非线性数据结构,直观的看,它是数据元素(在树中称为节点)按分支关系组织起来的结构,很像自然界中树那样.树结构在客观世界中广泛存在,如人类社会的族谱和各种社会组织机构都可用树形 ...

  7. Vtable内存布局分析

    vtale 内存布局分析 虚函数表指针与虚函数表布局 考虑如下的 class: class A { public: int a; virtual void f1() {} virtual void f ...

  8. Hydra爆破神器使用

    参数详解: -R 根据上一次进度继续破解-S 使用SSL协议连接-s 指定端口-l 指定用户名-L 指定用户名字典(文件)-p 指定密码破解-P 指定密码字典(文件)-e 空密码探测和指定用户密码探测 ...

  9. shark恒破解笔记1-壳内寻找注册码

    记录学习shark恒大教程的学习记录 壳内寻找注册码 OD打开 明显有壳 F9先运行程序 2.Ctrl+G输入401000到解码段,如果出现db ** 说明已经解码过,脱离了程序本身的壳 鼠标右键-& ...

  10. Unity 登录白屏或者黑屏

    如果有一天,突然,你的Unity抽风了,登录界面白屏或者黑屏,不要急着重装.我重装了3次,第四次我再也忍不住了,终于出手了. 找到 C:\Users\hasee\AppData\Roaming\Uni ...