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

如何为JavaScript计算器实现上标输入切换按钮

实现计算器上标模式切换功能

核心思路

  1. 在计算器类中添加上标模式状态标记,跟踪当前是否处于上标输入模式
  2. 将显示更新逻辑从innerText改为innerHTML,支持插入HTML标签实现上标效果
  3. 修改内容追加方法,根据模式状态决定是否将输入内容包裹在<sup>标签中
  4. 切换按钮点击时更新模式状态,并同步按钮样式反馈当前状态

修改后的完整代码

HTML(保持原结构无需改动)

<div class="form-group">
   <div data-current-content contenteditable="true" class="form-control form-control-lg" style="min-height: 50px;">
   </div>
</div>
<div class="container mx-0">
    <div class="row">
        <div class="col">
            <div class="calculator-grid">
                <button data-append type="button"><i>x</i></button>
                <button data-append type="button"><i>y</i></button>
                <button data-power2 type="button">a<sup>2</sup></button>
                <button data-powers class="button" type="button">a<sup>b</sup></button>
                <button data-append type="button">(</button>
                <button data-append type="button">)</button>
                <button data-append type="button">&lt;</button>
                <button data-append type="button">&gt;</button>
                <button data-append type="button">|a|</button>
                <button data-append type="button">,</button>
                <button data-append type="button">&le;</button>
                <button data-append type="button">&ge;</button>
                <button data-append type="button">&#8730;</button>
                <button data-append type="button">&#960;</button>
            </div>
        </div>
    </div>
</div>

JavaScript(关键修改标注)

class Calculator {
  constructor(current_content) {
    this.current_content = current_content
    this.clear()
    // 新增:初始化上标模式状态为关闭
    this.isPowerMode = false
  }

  refresh() {
    // 修改:用innerHTML获取当前内容,保留HTML结构
    this.currentOperand = this.current_content.innerHTML
  }

  clear() {
    this.currentOperand = ''
  }

  delete() {
    // 优化:处理HTML内容的删除,避免破坏标签结构
    const selection = window.getSelection()
    if (selection.rangeCount > 0 && !selection.isCollapsed) {
      selection.deleteFromDocument()
      this.currentOperand = this.current_content.innerHTML
    } else {
      // 从末尾删除时自动处理标签闭合
      this.currentOperand = this.currentOperand.replace(/(<sup>[^<]*?)$|([^<]*)$/, '')
    }
  }

  appendContent(content) {
    // 新增:根据上标模式决定是否包裹标签
    if (this.isPowerMode) {
      // 避免嵌套上标标签
      if (!this.currentOperand.endsWith('</sup>') && !this.currentOperand.endsWith('<sup>')) {
        this.currentOperand += `<sup>${content}</sup>`
      } else {
        // 已在上标内则直接追加内容
        this.currentOperand = this.currentOperand.replace(/(<sup>)(.*)$/, `$1$2${content}`)
      }
    } else {
      this.currentOperand += content
    }
  }

  appendPower2() {
    // 直接追加平方符号,不受上标模式影响
    this.currentOperand += '\u00B2'
  }

  updateDisplay() {
    // 修改:用innerHTML更新显示,渲染HTML标签
    this.current_content.innerHTML = this.currentOperand
  }

  // 新增:切换上标模式的方法
  togglePowerMode() {
    this.isPowerMode = !this.isPowerMode
  }
}

const numberButtons = document.querySelectorAll('[data-append]')
const powerButtons = document.querySelectorAll('[data-powers]')
const powerButton2 = document.querySelectorAll('[data-power2]')
const deleteButton = document.querySelector('[data-delete]')
const allClearButton = document.querySelector('[data-all-clear]')
const current_content = document.querySelector('[data-current-content]')

const calculator = new Calculator(current_content)

numberButtons.forEach(button => {
  button.addEventListener('click', () => {
    calculator.refresh()
    // 修改:调用新增的appendContent方法
    calculator.appendContent(button.innerText)
    calculator.updateDisplay()
    // 优化:自动将光标移到内容末尾
    const range = document.createRange()
    const sel = window.getSelection()
    range.selectNodeContents(current_content)
    range.collapse(false)
    sel.removeAllRanges()
    sel.addRange(range)
  })
})

powerButtons.forEach(button => {
  button.addEventListener("click", function(){
    // 切换计算器上标模式
    calculator.togglePowerMode()
    // 更新按钮样式反馈状态
    this.style.backgroundColor = calculator.isPowerMode ? 'yellow' : 'white'
  })
});

powerButton2.forEach(button => {
  button.addEventListener('click', () => {
    calculator.refresh()
    calculator.appendPower2()
    calculator.updateDisplay()
  })
})

allClearButton.addEventListener('click', () => {
  calculator.clear()
  calculator.updateDisplay()
})

deleteButton.addEventListener('click', () => {
  calculator.delete()
  calculator.updateDisplay()
})

关键修改说明

  • 模式状态管理:新增isPowerMode变量跟踪上标模式,通过togglePowerMode()方法切换状态
  • HTML内容支持:将内容读写逻辑从innerText改为innerHTML,允许插入<sup>标签实现上标
  • 智能追加逻辑:appendContent()自动判断是否已在上标标签内,避免重复嵌套,保证HTML结构正确
  • 删除逻辑优化:处理HTML内容的删除,既支持选中删除,也支持末尾删除时不破坏标签结构
  • 用户体验优化:输入后自动将光标移到内容末尾,保持连续输入的流畅性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 17:55:28