小费计算器的Javascript

3
我正在创建一个小费计算器,根据账单金额、小费百分比和人数计算小费金额(这些都是用户输入的)。我已经使用JavaScript创建了一个脚本,但它不起作用,我不确定为什么。我是否以错误的方式调用该函数?我在函数或for循环中是否犯了任何错误?对于代码片段中混乱的布局,我感到抱歉,我正在采用以移动设备为先的方法,并且仍在努力完成桌面布局。

let allButtons = document.getElementsByClassName('btn');
let noOfButtons = allButtons.length;
let i;

function tipCalculate(e) {
  let billAmount = parseFloat(document.getElementById('bill__amount').value);
  let tipPercent = e.target.value;
  let noOfPeople = document.getElementById('people-no').value;
  let tipAmountPerPerson = billAmount / 100 * tipPercent / noOfPeople;
  let totalAmountPerPerson = (billAmount + (billAmount / 100 * tipPercent)) / noOfPeople;
  document.getElementByClassName('tip-amount-display').innerHTML = tipAmountPerPerson;
  document.getElementByClassName('total-amount-display').innerHTML = totalAmountPerPerson;
}

// append event listeners to each button
for (i = 0; i < noOfButtons; i++) {
  allButtons[i].addEventListener('click', tipCalculate);
}
@import url('https://fonts.googleapis.com/css2?family=Space+Mono:wght@400;700&display=swap');
:root {
  --clr-primary: hsl(172, 67%, 45%);
  --clr-neutral-100: hsl(0, 0%, 100%);
  --clr-neutral-200: hsl(189, 41%, 97%);
  --clr-neutral-300: hsl(185, 41%, 84%);
  --clr-neutral-400: hsl(184, 14%, 56%);
  --clr-neutral-500: hsl(186, 14%, 43%);
  --clr-neutral-600: hsl(183, 100%, 15%);
}

*,
*::after,
*::before {
  box-sizing: border-box;
}

h2 {
  margin: 0;
  font-size: 1rem;
}

body {
  margin: 0;
  font-family: 'Space Mono', monospace;
  background: var(--clr-neutral-300);
  font-size: 1rem;
  font-weight: 400;
}

button {
  font-family: 'Space Mono', monospace;
  text-transform: uppercase;
  border: none;
  padding: 0.3em 0.6em;
  border-radius: 0.45rem;
  font-size: 1.4rem;
  font-weight: 700;
}

.btn-main {
  background-color: var(--clr-neutral-600);
  color: var(--clr-neutral-100);
}

.btn-main:hover,
.btn-main:focus {
  background-color: var(--clr-primary);
  color: var(--clr-neutral-600);
}

.btn-inverse {
  background-color: var(--clr-primary);
  color: var(--clr-neutral-600);
}

.title {
  color: var(--clr-neutral-500);
  text-align: center;
  letter-spacing: .35em;
  padding: 1em 0;
}

form {
  background: var(--clr-neutral-100);
  border-radius: 1.8rem 1.8rem 0 0;
}

.accent-title {
  color: var(--clr-neutral-500);
}

.accent-title-light {
  color: var(--clr-neutral-400);
  font-size: .8rem;
}

.tip-amount {
  background: var(--clr-neutral-600);
  border-radius: 1rem;
  padding: 1.6rem;
  display: flex;
  /* flex-direction: column; */
  flex-wrap: wrap;
  justify-content: space-between;
}

.neutral-title {
  color: var(--clr-neutral-100);
}

input {
  border: none;
  background-color: var(--clr-neutral-200);
  width: 100%;
  border-radius: .25rem;
}

.bill__amount,
.people-no {
  height: 40px;
  text-align: right;
  font-family: 'Space Mono', monospace;
  font-size: 24px;
  font-weight: 700;
  color: var(--clr-neutral-600);
  padding-right: .8rem;
}

.bill__amount {
  background-image: url(../images/icon-dollar.svg);
  background-repeat: no-repeat;
  background-position: left center;
  background-origin: content-box;
  padding-left: .8rem;
}

.people-no {
  background-image: url(../images/icon-person.svg);
  background-repeat: no-repeat;
  background-position: left center;
  background-origin: content-box;
  padding-left: .8rem;
}

div+div {
  margin-top: 2em;
}

.calculator {
  padding: 2rem;
}

.tip__btns {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

.accent-title-light {
  margin-top: 0%;
}

.reset {
  width: 100%;
  margin-top: 1rem;
}

.tip__heading {
  margin-bottom: .9rem;
}

.tip__custom {
  font-family: 'Space Mono', monospace;
  font-size: 1.3rem;
  font-weight: 700;
  letter-spacing: .1rem;
  text-align: right;
  padding-right: .8rem;
}

.bill__heading,
.no-of-people__heading {
  margin-bottom: .6rem;
}

.tip-amount-display,
.total-amount-display {
  /* text-align: right; */
  color: var(--clr-primary);
  font-size: 24px;
}

.total-amount-display {
  margin-top: 1.25rem;
}

.tip-amount-display {
  align-self: start;
  margin-top: .4rem;
}

.col+.col {
  margin-top: 0;
}

@media (min-width: 768px) {
  form {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    align-content: stretch;
    width: 50%;
    margin: 0 auto;
    border-radius: 1.8rem 1.8rem 1.8rem 1.8rem;
  }
  form>* {
    flex: 1 1 50%;
  }
  .attribution {
    align-self: flex-end;
  }
  div+div {
    margin-top: 0;
  }
}

.attribution {
  font-size: 11px;
  text-align: center;
}

.attribution a {
  color: hsl(228, 45%, 44%);
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <!-- displays site properly based on user's device -->
  <link rel="stylesheet" href="css/style.css">
  <link rel="icon" type="image/png" sizes="32x32" href="./images/favicon-32x32.png">
  <script src="js/tip.js"></script>

  <title>Frontend Mentor | Tip calculator app</title>

</head>

<body>
  <h1 class="title">SPLI<br>TTER</h1>
  <form class="calculator">

    <div class="main-cols">
      <div class="bill">

        <h2 class="bill__heading"><label for="bill__amount" class="accent-title">Bill</label></h2>
        <input type="text" name="bill__amount" id="bill__amount" class="bill__amount" placeholder="0">

      </div>
      <div class="tip">

        <h2 class="tip__heading"><label for="" class="accent-title">Select Tip %</label></h2>
        <div class="tip__btns">
          <button type="button" class="btn btn-main">5%</button>
          <button type="button" class="btn btn-main">10%</button>
          <button type="button" class="btn btn-main">15%</button>
          <button type="button" class="btn btn-main">25%</button>
          <button type="button" class="btn btn-main">50%</button>
          <input type="text" name="tip__custom" class="tip__custom" id="tip__custom" placeholder="Custom">
        </div>
      </div>

      <div class="no-of-people">
        <h2 class="no-of-people__heading"><label for="people-no" class="accent-title">Number of People</label></h2>
        <input type="text" name="people-no" id="people-no" class="people-no" placeholder="0">
      </div>
    </div>

    <div class="main-cols">
      <div class="tip-amount">

        <div class="col">
          <h2 class="neutral-title">Tip Amount</h2>
          <h3 class="accent-title-light ">/ person</h3>
          <h2 class="neutral-title">Total</h2>
          <h3 class="accent-title-light">/ person</h3>
        </div>
        <div class="col">
          <h2 class="tip-amount-display">$0.00</h2>
          <h2 class="total-amount-display">$0.00</h2>
        </div>
        <button class="btn-inverse reset">Reset</button>
      </div>
    </div>

    <div class="attribution">
      Challenge by <a href="https://www.frontendmentor.io?ref=challenge" target="_blank">Frontend Mentor</a>. Coded by <a href="#">Sachin Jadhav</a>.
    </div>
  </form>


</body>

</html>

2个回答

4

问题1

应该使用 getElementsByClassName 而不是 getElementByClassName(你漏掉了's')。 以下是如何使用它:https://developer.mozilla.org/zh-CN/docs/Web/API/Document/getElementsByClassName

具体地说,document.getElementsByClassName('test')[0] 会对你有用,可以获取该类别中的第一个元素。

你的代码将如下所示:

document.getElementsByClassName('tip-amount-display')[0].innerHTML = tipAmountPerPerson;
//                 ^                                 ^

或者您可以使用querySelector来使用CSS选择器在DOM中查找元素。

问题 2.1

e.target.value始终为空字符串(对其进行数学运算将导致NaN)。 这是因为被点击的HTML元素上没有value属性。要解决此问题,请在HTML中的按钮中添加value="5",例如:

<button type="button" value="5" class="btn btn-main">5%</button>
<button type="button" value="10" class="btn btn-main">10%</button>
<!-- ... -->

问题 2.2

当没有输入值时,document.getElementById('people-no').value也是一个空字符串。要解决这个问题,您可以检查它的真实性,因为空字符串和0将会是虚假的,您可以用1替换它们。

详细版本:

let noOfPeople = document.getElementById('people-no').value;
  if (!noOfPeople) {
    noOfPeople = 1;
  }

使用短路求值的简短版本:

let noOfPeople = document.getElementById('people-no').value || 1;

这里有一个可用的 JSFiddle:https://jsfiddle.net/zg6t4o1a/


1
我添加了 s 和 [0],但脚本仍然无法更改小费金额/人和总金额/人。 - Sachin Jadhav
@SachinJadhav 我已经编辑了我的答案,涵盖了我发现的所有问题。 - Max
1
@Max 谢谢你的代码,它很有效。我甚至没有注意到我缺少了按钮的值,我之前添加过它,但出于某种原因将其删除了。 - Sachin Jadhav

0
let button = document.querySelector("button");
let fun = () => { let totalamount = +document.getElementById("amount").value let select = +document.getElementById("select").value; let totalpeople = +document.getElementById("peo").value; let finale =document.getElementById("h3");let absolute = (totalamount * select) / totalpeople; finale.textContent = absolute;if (totalamount <= 0) { alert("Your entered value is invalid");  }};button.addEventListener("click", fun);

虽然这段代码可能解决了问题,但包括解释如何以及为什么解决问题将有助于提高您的帖子质量,可能会得到更多赞。请记住,您正在回答未来读者的问题,而不仅仅是现在提问的人。请[编辑]您的答案以添加解释并指出适用的限制和假设。 - jmoerdyk
你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心找到有关如何编写良好答案的更多信息。 - Community

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