如何为JavaScript计算器实现上标输入切换按钮
实现计算器上标模式切换功能
核心思路
- 在计算器类中添加上标模式状态标记,跟踪当前是否处于上标输入模式
- 将显示更新逻辑从
innerText改为innerHTML,支持插入HTML标签实现上标效果 - 修改内容追加方法,根据模式状态决定是否将输入内容包裹在
<sup>标签中 - 切换按钮点击时更新模式状态,并同步按钮样式反馈当前状态
修改后的完整代码
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"><</button> <button data-append type="button">></button> <button data-append type="button">|a|</button> <button data-append type="button">,</button> <button data-append type="button">≤</button> <button data-append type="button">≥</button> <button data-append type="button">√</button> <button data-append type="button">π</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
相关产品推荐
相关产品推荐

