You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FreeCodeCamp计算器项目问题:无法实现负号的双重功能

计算器负号按钮双重功能实现问题

我正在为FreeCodeCamp前端开发库项目制作计算器,卡在实现负号按钮的双重功能上——需要让“-”按钮同时支持减法运算与输入负数(例如5*-5)。此前通过+/-按钮实现了负数输入,但该方案无法通过FCC测试,尽管功能正常。已尝试谷歌搜索、查看FCC论坛、使用ChatGPT等方法,参考Useful Programmer的视频完成了计算器主体,但未找到该问题的解决方法。

解决方案

要让“-”按钮同时实现减法运算和负数输入,需在updateDisplay函数中针对subtract操作添加场景判断,区分何时作为负号输入、何时作为减法运算:

  • 当前显示内容为0时,点击“-”应输入负数符号
  • 当前显示内容末尾是运算符(+、-、*、/)时,点击“-”应输入负数符号
  • 其他场景下执行减法运算逻辑

修改后的完整代码

HTML(无需修改)

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ" crossorigin="anonymous">
<script>
 let  trailingResult = 0;
let operationOptions = ['divide', 'multiply', 'subtract','add'];
let workingOperation ="";

function updateDisplay(input) {
  let display = document.getElementById("display");

  // 专门处理subtract的双重功能
  if (input === 'subtract') {
    // 场景1:当前显示是0,输入负数
    if (display.innerHTML === "0") {
      display.innerHTML = "-";
      return;
    }
    // 场景2:当前显示末尾是运算符,输入负数
    const lastChar = display.innerHTML.slice(-1);
    const opSymbols = ['+', '-', '*', '/'];
    if (opSymbols.includes(lastChar)) {
      display.innerHTML += "-";
      return;
    }
    // 其他情况执行减法运算逻辑,复用原有代码
  }

  if (display.innerHTML === "0" && operationOptions.indexOf(input) === -1) {
    if (input === 'decimal') {
      display.innerHTML = "0.";
    } else {
      display.innerHTML = input;
    }
  } else if (operationOptions.indexOf(input) >= 0){
    // 处理无初始操作数的情况
    if (workingOperation === "") {
      workingOperation = input;
      trailingResult = display.innerHTML;
      display.innerHTML = 0;
    } else {
      const lastChar = display.innerHTML.slice(-1);
      const opSymbols = ['+', '-', '*', '/'];
      if (opSymbols.includes(lastChar)) {
        workingOperation = input;
      } else {
        trailingResult = calculate(trailingResult, display.innerHTML, workingOperation);
        display.innerHTML = 0;
        workingOperation = input;
      }
    }
  } else if (input === "equals") {
    let result = calculate(trailingResult, display.innerHTML, workingOperation);
    display.innerHTML = result;
    trailingResult = parseFloat(result);
    workingOperation = "";
  } else if (input === "decimal"){
    if (display.innerHTML.indexOf(".") === -1){
      display.innerHTML += ".";
    }
  } else {
    display.innerHTML += input;
  }
}

function clearDisplay() {
  let display = document.getElementById("display");
  display.innerHTML = 0;
}

function calculate(firstNumber, secondNumber, operation) {
  let result;
  firstNumber = parseFloat(firstNumber);
  secondNumber = parseFloat(secondNumber);
  switch (operation) {
    case "add":
      result = firstNumber + secondNumber;
      break;
    case "subtract":
      result = firstNumber - secondNumber;
      break;
    case "multiply":
      result = firstNumber * secondNumber;
      break;
    case "divide":
      result = firstNumber / secondNumber;
      break;
    default:
      result = secondNumber; // 处理无前置运算的情况,如直接输入-5后按等于
  }
  return result;
}

</script>

</head>
<body>
    <title>Calculator by Diemer</title>

<div class="calculator-grid">
    <div class="display" id="display"> 
        <div class="previous-operand"></div>
        <div class="current-operand"> </div>
    </div>
    <button onclick="clearDisplay()"  id="clear"  class="span-two">AC</button>
    <button onclick="updateDisplay('divide')" id="divide">/</button>
    <button onclick="updateDisplay('multiply')"id="multiply">*</button>
    <button onclick="updateDisplay(7)" id="seven">7</button>
    <button onclick="updateDisplay(8)" id="eight">8</button>
    <button onclick="updateDisplay(9)" id="nine">9</button>
    <button onclick="updateDisplay('subtract')" id="subtract">-</button>
    <button onclick="updateDisplay(4)" id="four">4</button>
    <button onclick="updateDisplay(5)" id="five">5</button>
    <button onclick="updateDisplay(6)" id="six">6</button>
    <button onclick="updateDisplay('add')" id="add">+</button>
    <button onclick="updateDisplay(1)" id="one">1</button>
    <button onclick="updateDisplay(2)" id="two">2</button>
    <button onclick="updateDisplay(3)" id="three">3</button>
    <button onclick="updateDisplay('decimal')" id="decimal">.</button>
   <!-- <button onclick="updateDisplay('-')" id="negative-value">+/-</button> -->
    <button onclick="updateDisplay(0)" id="zero">0</button>
    <button onclick="updateDisplay('equals')" class="span-two" id="equals">=</button>
    
</div>
</body>

<script src="https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ENjdO4Dr2bkBIFxQpeoTz1HIcje39Wm4jDKdf19U8gI4ddQ3GYNS7NTKfAdVQSZe" crossorigin="anonymous"></script>

</html>

CSS(无需修改)

*, *::before, *::after {
    box-sizing: border-box;
  }
  
  body {
    margin: 0;
    background: linear-gradient(to right, #00aaff, #00ff6c);
  }
  
  .calculator-grid {
    display: grid;
    margin-top: 4rem;
    margin-bottom: 4rem;
    justify-content: center;
    grid-template-columns: repeat(4, 6rem);
    grid-template-rows: minmax(7rem, auto) repeat(5, 6rem);
  }
  
  .calculator-grid > button {
    cursor: pointer;
    font-size: 2rem;
    border: 1px solid white;
    outline: none;
    background-color: rgba(255,255,255, .75);
  }
  
  .calculator-grid > button:hover,
  .calculator-grid > button:focus {
    background-color: rgba(255,255,255, .9);
  }
  
  .span-two {
    grid-column: span 2;
  }
  
  .display {
    grid-column: 1 /  -1;
    background-color: rgb(0,0,0);
    color: white;
    font-size: 1,5rem;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    justify-content: space-around;
    padding: .75rem;
    word-wrap: break-word;
    word-break: break-all;
  }

关键修改说明

  1. 新增subtract场景判断:在updateDisplay开头添加针对subtract的特殊处理,判断当前是否需要输入负号
  2. 运算符末尾判断优化:用opSymbols数组直接存储运算符符号,简化末尾字符的判断逻辑
  3. calculate函数默认处理:在switch的default分支返回secondNumber,处理直接输入负数后按等于的场景

内容的提问来源于stack exchange,提问作者Diem3r

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 17:32:20