新手JavaScript小费计算器问题

3

我刚刚开始学习 JavaScript。我将要学习 DOM 操作,对很多 JavaScript 知识还很陌生...从我的代码中你可能就能看出来!

我正在尝试制作小费计算器(我想这是新手常做的项目),但是在 DOM 方面和如何选择某些输入元素(文本和单选按钮)以及提交它们方面遇到了困难。

请帮我修改下面的代码,提供任何建议都非常感谢。我愿意接受教训并改掉所有错误,非常渴望学习正确操作!

<form class="container">
        <h2>Tip Calculator</h2>
        <p>Enter Bill Amount</p>
        <input type="text" class="input-styles" placeholder="£££" id="bill-amount">
        <p>Select Percentage Of Bill</p>
        <div class="radio-container">
            <div class="radio-styles">                        <p>10%</p>
                <input type="radio" class="radio-styles" name="tip-percent" value="0.1">
            </div>
            <div class="radio-styles">
                <p>15%</p>
                <input type="radio" class="radio-styles" name="tip-percent" value="0.15">
            </div>
              <div class="radio-styles">
                <p>20%</p>
                <input type="radio" class="radio-styles" name="tip-percent" value="0.2">
            </div>
            <div class="radio-styles">
                <p>25%</p>
                <input type="radio" class="radio-styles" name="tip-percent" value="0.25">
            </div>
        </div>
        <div class="submit-container">
            <button type="submit" name="tip-submit" id="submit-button">submit</button>
        </div>
        <div class="totals-container">
            <div class="totals">
                <h2>Tip To Pay</h2>
                <h2 id="tip-to-pay"></h2>
                <h2 id="bill-final">Total Bill To Pay</h2>
                <h2 id="bill-to-pay"></h2>
            </div>
        </div>
    </form>

以下是Javascript代码...

var bill, percent, tip, finalBill;


document.getElementById('submit-button').addEventListener('click', function() {

// get bill amount
bill = document.getElementById('bill-amount').value

//get percent amount from checkboxes
percent = document.getElementsByName('tip-percent').checked;
tip = calcTip();
finalBill = finalAmount();

// edit results in html
document.getElementById('tip-to-pay').textContent = tip;
document.getElementById('bill-to-pay').textContent = finalBill;

// display result
document.querySelector('.totals-container').style.display = 'flex';

}

function calcTip() {
    tip = percent * bill
}

function finalAmount() {
    finalBill = tip + bill
}

如果您查看下面的画笔,可能会更容易理解这个问题! https://codepen.io/rickwall/pen/WNbpmoW


7
你是一个新手,但你提交了一个格式良好的问题,并附带了一个可供我们尝试的演示。赞!你在StackOverflow上有前途 :-) - Jorge Fuentes González
3
问题在于这不是代码审查(有一个网站专门用于此),我们需要确切的问题和确切的问题描述。我不知道你具体遇到了什么问题。我所看到的唯一问题是你提交表单后会丢失网页。你希望在按下按钮时阻止其跳转,只更新HTML内容吗? - Jorge Fuentes González
2
您也可以在提问中使用代码片段,以获得与 Codepen 相似的功能,这将允许其他用户在问题主体中查看您的代码,并记录错误,以便您可以发现问题中的错误。 - Shiny
2
我现在看到了更多的问题。你需要去https://codereview.stackexchange.com/并在那里提问 :-) - Jorge Fuentes González
请注意,代码审查仅适用于您想要改进的可工作代码。如果您的代码无法正常工作或未按照您的意愿执行,则应在此处提出问题,但您应该尽可能缩小问题范围,只询问您遇到麻烦的部分,以便回答者更容易解答。 - John Montgomery
显示剩余3条评论
1个回答

1

HTML

在你的 HTML 中,你用 <form class="container"> 包裹了你的计算器 - 表单通常用于向 web 服务器发送数据,进行提交或验证等操作。在这种情况下,你只是将其用作容器,因此可以使用标准的 <div>

这导致您的计算器在提交后消失

JavaScript

作用域 - 最初,您在全局作用域中定义了所有变量,而不是函数作用域。这通常会引起问题,比如变量覆盖、跟踪变更丢失、通常是意料之外的行为 - 您可以阅读更多相关内容

函数 - 您的函数可能是作用域的产物,但通常情况下,您希望函数接受一个输入,并返回一个值,而不是修改函数作用域之外的值 - 返回输出有助于避免意外更改,而使用参数输入值则可以实现更多控制和可读性。

在这段代码中,我会倾向于直接进行数学计算,而不使用函数,因为它很简单且只调用一次 - 但你可以自由选择。
// This will change the value of tip globally, while also using set variables for percent and bill
function calcTip () {
  tip = percent * bill
}

// This allows us to return the output of our function to our chosen variable
// while also taking the inputs we want

function calcTip (percent, bill) {
  return percent * bill;
}

let tip = calcTip(0.10, 120); // returns 12;

从MDN文档中了解更多有关函数的信息


类型 - 在您的主函数中,您正在检索元素的.value,并将其分配给billpercent。但是,无论输入是字符"a"还是字符"2",.value都会返回一个字符串 - 当您尝试添加值时,这会导致问题,因为加法运算符+在与字符串数字一起使用时会执行不同的操作。

例如,当与字符串数字一起使用时,它只会将两个变量连接在一起,而不是像您可能期望的那样将它们相加。

let a = "5"; // Type: String
let b = 120; // Type: Number

a + b // "5120"

使用两个数字时,正确的行为将会显示。
let a = 5;   // Type: Number
let b = 120; // Type: Number

a + b // 125

在您的情况下,我们可以使用parseInt(x)parseFloat(x)将字符串值billpercent转换为数字 - parseInt将其转换为整数,而parseFloat将其转换为浮点数。请注意保留HTML标签。

这段代码片段中还有一些小的更改,但这只是在您将其发布到代码审查之前快速为您做的一些事情 - 绝对不是完成此操作的绝对正确方式,有很多方法,但希望这可以帮助您向前迈进。

document.getElementById('submit-button').addEventListener('click', function() {
  // Get bill amount
  let bill = parseInt(document.getElementById('bill-amount').value);

  // Get percent from selected checkbox
  /* let percent = document.getElementsByName('tip-percent'); */
  let percent = parseFloat(document.querySelector('input[name="tip-percent"]:checked').value);
  
  // No reason to have these as functions if they're simple & only called once
  let tip = percent * bill;
  let finalBill = bill + tip;

  // Add results in html
  document.getElementById('tip-to-pay').textContent = '$' + tip;
  document.getElementById('bill-to-pay').textContent = '$' + finalBill;

  // Dislay result
  document.querySelector('.totals-container').style.display = 'flex';
})
* {
  margin: 0;
  padding: 0;
}

html {
  font-family: zilla slab;
  font-size: 18px;
  font-weight: 300;
  background-image: url(imgs/restaurant.jpg);
  background-position: center;
}

.page {
  display: flex;
  justify-content: center;
  align-items: center;
}

.container {
  display: flex;
  justify-content: center;
  flex-direction: column;
  background-color: rgba(204, 238, 255, 0.9);
  padding: 50px 100px 50px 100px;
  margin-top: 2%;
  text-align: center;
  box-shadow: 0px 8px 40px rgba(0, 0, 0, 0.5), 0px 10px 20px rgba(0, 0, 0, 0.7);
  border-radius: 40px;
}

.container>h2 {
  padding-bottom: 1.6rem;
  font-size: 2.5rem;
}

.container>p {
  padding-bottom: 1rem;
  font-size: 1.5rem;
}

.container>input {
  text-align: center;
  padding: 4px;
  font-size: 1.2rem;
  width: 160px;
  margin-left: 19%;
  margin-bottom: 1rem;
}

.radio-container {
  display: flex;
  justify-content: space-between;
}

.radio-box {
  display: flex;
  text-align: center;
  align-items: center;
  flex-direction: column;
}

.radio-styles {
  margin: 10px 0 1.2rem 0;
  cursor: pointer;
  outline: none;
}

button {
  padding: 8px 40px 8px 40px;
  text-transform: uppercase;
  background-color: #fff;
  border: none;
  border-radius: 45px;
  box-shadow: 0px 8px 15px rgba(0, 0, 0, 0.3);
  transition: all 0.3s ease 0s;
  cursor: pointer;
  outline: none;
  font-family: zilla slab;
  font-weight: 300;
  font-size: 1rem;
}

.totals-container {
  display: none;
}

.totals {
  display: flex;
  flex-direction: column;
}

#bill-final {
  font-size: 2rem;
}

.totals h2 {
  padding-bottom: 1.6rem;
}
<div class="page">
  <div class="container">
    <h2>Tip Calculator</h2>
    <p>Enter Bill Amount</p>
    <input type="text" class="input-styles" placeholder="£££" id="bill-amount">
    <p>Select Percentage Of Bill</p>
    <div class="radio-container">
      <div class="radio-styles">
        <p>10%</p>
        <input type="radio" class="radio-styles" name="tip-percent" value="0.10">
      </div>
      <div class="radio-styles">
        <p>15%</p>
        <input type="radio" class="radio-styles" name="tip-percent" value="0.15">
      </div>
      <div class="radio-styles">
        <p>20%</p>
        <input type="radio" class="radio-styles" name="tip-percent" value="0.20">
      </div>
      <div class="radio-styles">
        <p>25%</p>
        <input type="radio" class="radio-styles" name="tip-percent" value="0.25">
      </div>
    </div>
    <div class="submit-container">
      <button type="submit" name="tip-submit" id="submit-button">submit</button>
    </div>
    <div class="totals-container">
      <div class="totals">
        <h2>Tip To Pay</h2>
        <h2 id="tip-to-pay"></h2>
        <h2 id="bill-final">Total Bill To Pay</h2>
        <h2 id="bill-to-pay"></h2>
      </div>
    </div>
  </div>
</div>


1
非常感谢Light提供的所有见解-非常感谢详细回复所花费的时间!当我在这里和CodePen运行代码时,一切似乎都很正常,这太棒了,我肯定可以根据您的输入进行工作,所以再次感谢:D奇怪的是,在Google Chrome中单击提交按钮后,似乎没有计算小费并显示小费金额和最终账单...有什么想法吗? - rickwall
我不确定,在谷歌浏览器中,它在我的电脑和你的Codepen上都能正常工作。 - Shiny

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接