JavaScript贷款计算器问题
我正在使用HTML、CSS、Javascript和Javascript中的元素:权威指南(第6版)完成贷款计算器示例 以下是JSFIDLE: 我的问题: 1) 图表没有显示出来。为什么? 2) 在JSFIDLE版本中输入数字时,单击“计算”按钮时不会发生任何事情。但是,当我在计算机上打开HTML页面时,该页面将正常工作。为什么? 我已经看过这本书的勘误表了。诚然,画布代码超出了我目前的技能水平,但我对HTML/CSS/JavaScript很熟悉。我手工编写了书中的例子。JsHint/console.log没有给出错误。有什么想法吗 HTMLJavaScript贷款计算器问题,javascript,html,css,canvas,Javascript,Html,Css,Canvas,我正在使用HTML、CSS、Javascript和Javascript中的元素:权威指南(第6版)完成贷款计算器示例 以下是JSFIDLE: 我的问题: 1) 图表没有显示出来。为什么? 2) 在JSFIDLE版本中输入数字时,单击“计算”按钮时不会发生任何事情。但是,当我在计算机上打开HTML页面时,该页面将正常工作。为什么? 我已经看过这本书的勘误表了。诚然,画布代码超出了我目前的技能水平,但我对HTML/CSS/JavaScript很熟悉。我手工编写了书中的例子。JsHint/consol
输入贷款数据:
贷款余额、累计权益和利息支付
贷款金额(元):
年息(%):
还款期(年):
Zipcode(用于查找贷方):
大致付款:
算计
每月付款:
$
付款总额:
$
利息总额:
$
发起人:
向以下其中一家优质贷款机构申请贷款:
JS
函数计算(){
//在中查找输入和输出元素
//文件
var金额=document.getElementById(“金额”);
var apr=document.getElementById(“apr”);
var years=document.getElementById(“年”);
var zipcode=document.getElementById(“zipcode”);
var payment=document.getElementById(“付款”);
var total=document.getElementById(“总计”);
var totalinterest=document.getElementById(“totalinterest”);
//从输入元素获取用户的输入。
//假设全部有效。将利息从
//将百分比转换为十进制,并从
//年利率转换为月利率。转换付款
//期间(以年为单位)到每月
//付款。
var principal=parseFloat(金额、价值);
var利息=浮动(四月值)/100/12;
风险值支付=浮动(年价值)*12;
//现在计算每月的付款数字。
var x=Math.pow(1+利息,付款);//Math.pow()计算幂
每月风险值=(本金*x*利息)/(x-1);
//如果结果是一个有限的数字,那么用户的输入是好的,并且
//我们要展示有意义的成果
if(有限(每月)){
//填写输出字段,四舍五入至小数点后2位
payment.innerHTML=每月.toFixed(2);
total.innerHTML=(每月*付款).toFixed(2);
totalinterest.innerHTML=((每月*付款)-本金).toFixed(2);
//保存用户的输入,以便我们可以在他们下次访问时恢复它
保存(amount.value、apr.value、years.value、zipcode.value);
//广告:查找并显示本地贷方,但忽略网络错误
尝试{//捕获大括号中出现的任何错误
//getLenders(amount.value、apr.value、years.value、zipcode.value);
}抓住(e){/*并忽略这些错误*/
}
//聊天贷款余额、利息和权益付款
图表(本金、利息、每月、付款);
}否则{
//Reslt不是一个数字或无穷大,这意味着输入是
//不完整或无效。请清除任何明显显示的输出。
payment.innterHTML=“;//删除这些元素的内容
total.innerHTML=“”;
totalinterest.innerHTML=“”;
chart();//不带参数,清除图表
}
}
//将用户的输入另存为localStorage对象的属性。那些
//当用户将来访问时,属性仍然存在
//在某些浏览器(例如Firefox)中,如果您
//从本地文件://URL运行该示例。然而,它确实在HTTP上工作。
功能保存(金额、四月、年、zipcode){
if(window.localStorage){//仅在浏览器支持的情况下执行此操作
localStorage.loan\u amount=金额;
localStorage.loan\u amount=apr;
localStorage.loan_amount=年;
localStorage.loan_amount=zipcode;
}
}
//首次加载文档时自动尝试还原输入字段。
window.onload=函数(){
//如果浏览器支持本地存储,并且我们有一些存储的数据
if(window.localStorage&&localStorage.loan\u金额){
document.getElementbyId(“金额”).value=localStorage.loan\u amount;
document.getElementbyId(“apr”).value=localStorage.loan\u apr;
document.getElementbyId(“年”).value=localStorage.loan\u years;
document.getElementbyId(“zipcode”).value=localStorage.loan\u zipcode;
}
};
//在HTML元素中绘制每月贷款余额、利息和权益的图表。
//如果调用时没有参数,则只需删除以前绘制的任何图表。
功能图(本金、利息、每月、付款){
var graph=document.getElementById(“graph”);//获取标记
graph.width=graph.width;//清除和重置画布元素的魔法
//如果我们在没有参数的情况下被调用,或者这个浏览器不支持
//图形在一个元素中,然后现在返回。
if(arguments.length==0 | |!graph.getContect)返回;
//为定义图形API的获取“上下文”对象
var g=graph.getContext(“2d”);//所有绘图都是使用此对象完成的
变量宽度=graph.wid
<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>
<td>Zipcode (to find lenders):</td>
<td>
<input id="zipcode" onchange="calculate();">
</td>
<tr>
<th>Approximate Payments:</th>
<td>
<button onclick="calculate();">Calculate</button>
</td>
</tr>
<tr>
<td>Monthly payment:</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>
function calculate() {
// Look up the input and output elements in the
// document
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 totalinterest = document.getElementById("totalinterest");
// Get the user's input from the input elements.
// Assume it is all valid. Convert interest from
// a percentage to a decimal, and convert from an
// annual rate to a monthly rate. Convert payment
// period in years to the number of monthly
// payments.
var principal = parseFloat(amount.value);
var interest = parseFloat(apr.value) / 100 / 12;
var payments = parseFloat(years.value) * 12;
// Now compute the monthly payment figure.
var x = Math.pow(1 + interest, payments); // Math.pow() computes powers
var monthly = (principal * x * interest) / (x - 1);
// If the result is a finite umber, the user's input was good and
// we have meaningful results to display
if (isFinite(monthly)) {
// Fill in the output fields, rounding to 2 decimal places
payment.innerHTML = monthly.toFixed(2);
total.innerHTML = (monthly * payments).toFixed(2);
totalinterest.innerHTML = ((monthly * payments) - principal).toFixed(2);
// Save the user's input so we can restore it the next they visit
save(amount.value, apr.value, years.value, zipcode.value);
// Advertise: find and display local lenders, but ignore network errors
try { // Catch any errors that occur within the curly braces
// getLenders(amount.value, apr.value, years.value, zipcode.value);
} catch (e) { /* And ignore those errors */
}
// Chat loan balance, and interest, and equity payments
chart(principal, interest, monthly, payments);
} else {
// Reslt was Not-a-Number or infinite, which means the input was
// incomplete or invalid. Clear any peviously displayed output.
payment.innterHTML = ""; // Erase the content of these elemts
total.innerHTML = "";
totalinterest.innerHTML = "";
chart(); // With no arguments, clears the chart
}
}
// Save the user's input as properties of the localStorage object. Those
// properties will still be there when the user visits in the future
// This storage feature will not work in some browsers (Firefox, e.g.) if you
// run the example from a local file:// URL. It does work over HTTP, however.
function save(amount, apr, years, zipcode) {
if (window.localStorage) { // Only do this if the browser supports it
localStorage.loan_amount = amount;
localStorage.loan_amount = apr;
localStorage.loan_amount = years;
localStorage.loan_amount = zipcode;
}
}
// Automatically attempt to restore input fields when the document first loads.
window.onload = function () {
//If the browser supports localStorage and we have some stored data
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;
}
};
//Chart montly loan balance, interest and equity in an HTML <canvas> element.
// If called with no arguments then just erase any previously drawn chart.
function chart(principal, interest, monthly, payments) {
var graph = document.getElementById("graph"); // Get the <canvas> tag
graph.width = graph.width; // Magic to clear and reset the canvas elemtn
// If we're called with no arguments, or ig this browser does not support
// graphics in a <canvas> elemtn, then just return now.
if (arguments.length === 0 || !graph.getContect) return;
// Get the "context" object for the <canvas> that defines the drawing API
var g = graph.getContext("2d"); // All drawing is done with this object
var width = graph.width,
height = graph.height; //Get canvas size
// These functions convert payment numbers and dollar amounts to pixels
function paymentToX(n) {
return n * width / payments;
}
function amountToY(a) {
return height - (a * height / (monthly * payments * 1.05));
}
// Payments are a straight line from (0,0) to (payments, monthly*payments)
g.moveTo(paymentToX(0), amountToY(0)); // Start at lower left
g.lineTo(paymentToX(payments), // Draw to upper right
amountToY(monthly * payments));
g.lineTo(paymentToX(payments), amountToY(0)); // Down to lower right
g.closePath(); // And back to start
g.fillStyle = "#f88"; // Light red
g.fill(); // Fill the triangle
g.font = "bold 12px sans-serif"; // Define a font
g.fillText("Total Interest Payments", 20, 20); // Draw text in legend
// Vumulative equity is non-linear and trickier to chart
var equity = 0;
g.beginPath(); // Begin a new shape
g.moveTo(paymentToX(0), amountToY()); // starting at lower-left
for (var p = 1; p <= payments; p++) {
// For each payment, figure out how much is interest
var thisMonthsInterest = (principal - equity) * interest;
equity += (monthly - thisMonthsInterest); // The rest goes to equity
g.lineTo(paymentToX(p), amountToY(equity)); //Line to this point
}
g.lineTo(paymentToX(payments), amountToY(0)); // Line back to X axis
g.closePath(); // And back to start point
g.fillStyle = "green"; // Now use green paint
g.fill(); // And fill area under curve
g.fillText("Total Equity", 20, 35); // Label it in green
// Loop again, as above, but chart loan balance as a thick black line
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); // The rest goes to equity
g.lineTo(paymentToX(p), amountToY(bal)); // Draw line to this point
}
g.lineWidth = 3; // Use a thick line
g.stroke(); // Deaw the balance curve
g.fillStyle = "black"; // Switch to black text
g.fillText("Loan Balance", 20, 50); // Legend entry
// Now make a yearly tick marks and year numbers on X acis
g.textAlign = "center"; // Center text over ticks
var y = amountToY(0); // Y coordinate of X axis
for (var year = 1; year * 12 <= payments; year++) { // For each year
var x = paymentToX(year * 12); // Compute tick position
g.fillRect(x - 0.5, y - 3, 1, 3); // Draw the tick
if (year == 1) g.fillText("Year", x, y - 5); // Label the axis
if (year % 5 === 0 && year * 12 !== payments) // Number every 5 years
g.fillText(String(year), x, y - 5);
}
// Mark payment amounts along the right edge
g.textAlign = "right"; //Right=justify text
g.textBaseline = "middle"; // Center it vertically
var ticks = [monthly * payments, principal]; // The two points we'll mark
var rightEdge = paymentToX(payments); //X coordinate of Y axis
for (var i = 0; i < ticks.length; i++) { // for each of the 2 points
var y = amountToY(ticks[i]); // Compute Y position of tick
g.fillRect(rightEdge - 3, y - 0.5, 3, 1); //Draw the tick mark
g.fillText(String(ticks[i].toFixed(0)), //And label it.
rightEdge - 5, y);
}
}
window.calculate = function(){