使用 jQuery 动态创建按钮的问题

我正在尝试将操作员按钮动态添加到我的计算器,但我只是运气不好。我已经创建了动态创建数字和操作员按钮的函数。数字已成功创建,但一旦我尝试添加运算符,就没有任何反应。我正在尝试使用 for-in 循环在我的括号按钮和求值按钮之间添加运算符。似乎当我在运算符之前创建评估按钮时,评估按钮已成功创建,但运算符却没有。如果我在评估按钮之前移动代码以创建运算符 ,则两者都不会出现。我相当确定问题出在我的 for-in 循环中,但我不太确定在哪里。非常感谢任何和所有帮助/指导!


 var opsData = {

  add: {

    precedence: 1,

    name: 'add',

    operation: function (a, b) {return a + b;},

    output: function (a, b) {return a + ' + ' + b;},

    buttonHTML: '+'

  },

  subtract: {

    precedence: 1,

    name: 'subtract',

    operation: function (a, b) {return a - b;},

    output: function (a, b) {return a + ' - ' + b;},

    buttonHTML: '-'

  },

  multiply: {

    precedence: 2,

    name: 'multiply',

    operation: function (a, b) {return a * b;},

    output: function (a, b) {return a + ' * ' + b;},

    buttonHTML: '*'

  },

  divide: {

    precedence: 2,

    name: 'divide',

    operation: function (a, b) {return a / b;},

    isInvalidInput: function (a, b) {return b == 0 ? 'division by 0' : false;},

    output: function (a, b) {return a + ' / ' + b;},

    buttonHTML: '/'

  }

}


$.fn.addButton = function(html, className, onclick) {

  $('<button />', {

    html: html,

    'class': 'button ' + className,

    click: onclick

    }).appendTo(this);

  return this;

}


var addOperatorButton = function(op, click) {

  $operators.addButton(op.buttonHTML, 'operator ' + op.name, function(e) {

    click.call(this, e);

    $currentCalc.text(inputStack.getCalculationString());

    $collapsedCalc.text(inputStack.getCalculationString(true));

    $input.text(inputStackgetPartialResult());

    $input.data({clearOnInput: true});

  });

};


var getInput = () => {

  var input = $input.text();

  return input.match(/error/i) ? 0 : parseFloat($input.text())

}


for (var i in opsData) {

  (function(i) {

    if (!opsData.buttonHTML[i]) return;

    addOperatorButton(opsData[i], () => {

      inputStack.push(getInput(), new Operation(opsData[i]));

    })

  }(i))

}

我的完整代码笔的链接在这里:https ://codepen.io/tazmancooks/pen/PoNwGMX


如果我的问题没有得到很好的表达,我深表歉意,总的来说,我对 jQuery 和 Javascript 还是很陌生。


温温酱
浏览 129回答 2
2回答

小怪兽爱吃肉

您错误地访问了opsData对象:在第 352 行if (!opsData.buttonHTML[i]) return;更改为if (!opsData[i].buttonHTML) return;按钮现在在那里,但您仍然需要更改 CSS。$(function() {&nbsp; var opsData = {&nbsp; &nbsp; add: {&nbsp; &nbsp; &nbsp; precedence: 1,&nbsp; &nbsp; &nbsp; name: 'add',&nbsp; &nbsp; &nbsp; operation: function(a, b) {&nbsp; &nbsp; &nbsp; &nbsp; return a + b;&nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; &nbsp; output: function(a, b) {&nbsp; &nbsp; &nbsp; &nbsp; return a + ' + ' + b;&nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; &nbsp; buttonHTML: '+'&nbsp; &nbsp; },&nbsp; &nbsp; subtract: {&nbsp; &nbsp; &nbsp; precedence: 1,&nbsp; &nbsp; &nbsp; name: 'subtract',&nbsp; &nbsp; &nbsp; operation: function(a, b) {&nbsp; &nbsp; &nbsp; &nbsp; return a - b;&nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; &nbsp; output: function(a, b) {&nbsp; &nbsp; &nbsp; &nbsp; return a + ' - ' + b;&nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; &nbsp; buttonHTML: '-'&nbsp; &nbsp; },&nbsp; &nbsp; multiply: {&nbsp; &nbsp; &nbsp; precedence: 2,&nbsp; &nbsp; &nbsp; name: 'multiply',&nbsp; &nbsp; &nbsp; operation: function(a, b) {&nbsp; &nbsp; &nbsp; &nbsp; return a * b;&nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; &nbsp; output: function(a, b) {&nbsp; &nbsp; &nbsp; &nbsp; return a + ' * ' + b;&nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; &nbsp; buttonHTML: '*'&nbsp; &nbsp; },&nbsp; &nbsp; divide: {&nbsp; &nbsp; &nbsp; precedence: 2,&nbsp; &nbsp; &nbsp; name: 'divide',&nbsp; &nbsp; &nbsp; operation: function(a, b) {&nbsp; &nbsp; &nbsp; &nbsp; return a / b;&nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; &nbsp; isInvalidInput: function(a, b) {&nbsp; &nbsp; &nbsp; &nbsp; return b == 0 ? 'division by 0' : false;&nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; &nbsp; output: function(a, b) {&nbsp; &nbsp; &nbsp; &nbsp; return a + ' / ' + b;&nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; &nbsp; buttonHTML: '/'&nbsp; &nbsp; }&nbsp; }&nbsp; var Operation = function(options) {&nbsp; &nbsp; var inputs = [];&nbsp; &nbsp; for (var key in options) {&nbsp; &nbsp; &nbsp; this[key] = options[key];&nbsp; &nbsp; };&nbsp; &nbsp; //Check if another input is needed, if not push current input to inputs array&nbsp; &nbsp; this.addInput = function(input) {&nbsp; &nbsp; &nbsp; if (this.isSaturated) return this;&nbsp; &nbsp; &nbsp; inputs.push(input)&nbsp; &nbsp; &nbsp; return this;&nbsp; &nbsp; }&nbsp; &nbsp; this.invalidInput = this.invalidInput || function() {&nbsp; &nbsp; &nbsp; return false;&nbsp; &nbsp; };&nbsp; &nbsp; //Check if operation already has all needed inputs&nbsp; &nbsp; this.isSaturated = () => {&nbsp; &nbsp; &nbsp; var inputCount = this.singleinput ? 1 : 2&nbsp; &nbsp; &nbsp; for (var i = 0; i < inputCount; i++) {&nbsp; &nbsp; &nbsp; &nbsp; if (inputs[i] === null || isNaN(inputs[i])) return false;&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; return true;&nbsp; &nbsp; }&nbsp; &nbsp; this.execute = () => {&nbsp; &nbsp; &nbsp; //If error is thrown, return&nbsp; &nbsp; &nbsp; if (this.error) return this;&nbsp; &nbsp; &nbsp; //Check if inputs are missing OR if operation was already executed&nbsp; &nbsp; &nbsp; if (!this.isSaturated || this.value != null) return this;&nbsp; &nbsp; &nbsp; //Map inputs to numerical values since inputs can also be operational objects [addition(1, multiplication(2, 3))]&nbsp; &nbsp; &nbsp; var inputValues = inputs.map(function(input) {&nbsp; &nbsp; &nbsp; &nbsp; return Number(input);&nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; //Throw an error if there is invalid input&nbsp; &nbsp; &nbsp; this.error = this.isInvalidInput.apply(this, inputValues);&nbsp; &nbsp; &nbsp; if (this.error) {&nbsp; &nbsp; &nbsp; &nbsp; throw new Error(this.error);&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; this.calculationString = this.getCalculationString();&nbsp; &nbsp; &nbsp; this.value = this.operation.apply(this, inputValues);&nbsp; &nbsp; &nbsp; return this&nbsp; &nbsp; }&nbsp; &nbsp; this.getCalculationString = function(lastInput, collapsed) {&nbsp; &nbsp; &nbsp; if (collapsed) {&nbsp; &nbsp; &nbsp; &nbsp; this.execute();&nbsp; &nbsp; &nbsp; &nbsp; if (this.value != null) return this.value.toString();&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; var singleInput = this.singleInput;&nbsp; &nbsp; &nbsp; //Maps inputs to a string&nbsp; &nbsp; &nbsp; var inputValues = inputs.map(function(input) {&nbsp; &nbsp; &nbsp; &nbsp; var inputValue = input.getCalculationString ?&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; input.getCalculationString(lastInput, collapsed) :&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; input.toString();&nbsp; &nbsp; &nbsp; &nbsp; //Remove parenthases from any single input operations&nbsp; &nbsp; &nbsp; &nbsp; return singleInput ? inputValue.replace(/^\((.*)\)$/g, '$1') : inputValue;&nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; return options.output.apply(this, inputValues.concat([lastInput]))&nbsp; &nbsp; }&nbsp; &nbsp; // Translate numerical value of the operation result&nbsp; &nbsp; // Execute operation if no result yet&nbsp; &nbsp; this.valueOf = () => {&nbsp; &nbsp; &nbsp; if (this.value == null) {&nbsp; &nbsp; &nbsp; &nbsp; this.execute()&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; return this.value&nbsp; &nbsp; }&nbsp; &nbsp; this.toString = () => {&nbsp; &nbsp; &nbsp; if (this.getCalculationString == null) {&nbsp; &nbsp; &nbsp; &nbsp; this.execute();&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; return this.getCalculationString();&nbsp; &nbsp; }&nbsp; &nbsp; var inputStack = (function() {&nbsp; &nbsp; &nbsp; var levels;&nbsp; &nbsp; &nbsp; var closedContext;&nbsp; &nbsp; &nbsp; var partialResult;&nbsp; &nbsp; &nbsp; var error;&nbsp; &nbsp; &nbsp; var Stack = function() {&nbsp; &nbsp; &nbsp; &nbsp; this.peek = function() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return this[this.length - 1];&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; };&nbsp; &nbsp; &nbsp; Stack.prototype = [];&nbsp; &nbsp; &nbsp; var reset = function() {&nbsp; &nbsp; &nbsp; &nbsp; levels = new Stack;&nbsp; &nbsp; &nbsp; &nbsp; levels.push(new Stack);&nbsp; &nbsp; &nbsp; &nbsp; closedContext = error = null&nbsp; &nbsp; &nbsp; };&nbsp; &nbsp; &nbsp; var wrapLastOperation = function(operation) {&nbsp; &nbsp; &nbsp; &nbsp; var stack = levels.peek();&nbsp; &nbsp; &nbsp; &nbsp; stack.push(operation.addInput(stack.pop()))&nbsp; &nbsp; &nbsp; &nbsp; collapse(operation.precedence)&nbsp; &nbsp; &nbsp; };&nbsp; &nbsp; &nbsp; var collapse = function(precedence) {&nbsp; &nbsp; &nbsp; &nbsp; var stack = levels.peek();&nbsp; &nbsp; &nbsp; &nbsp; var currentOperation = stack.pop();&nbsp; &nbsp; &nbsp; &nbsp; var previousOperation = stack.peek()&nbsp; &nbsp; &nbsp; &nbsp; if (!currentOperation) return;&nbsp; &nbsp; &nbsp; &nbsp; if (!currentOperation.isSaturated()) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; stack.push(currentOperation);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; partialResult = Number(currentOperation);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } catch (e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; partialResult = error = 'Error: ' + e.message;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; };&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (previousOperation && previousOperation.precedence >= precedence) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; previousOperation.addInput(currentOperation);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; collapse(precedence);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; stack.push(currentOperation);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; };&nbsp; &nbsp; &nbsp; reset();&nbsp; &nbsp; &nbsp; return {&nbsp; &nbsp; &nbsp; &nbsp; push: function(number, operation) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //If an error already exists, reset&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; error && reset();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var stack = levels.peek();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var lastOperation = stack.peek();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var input = closedContext || number;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; closedContext = null&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; partialResult = Number(input);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!lastOperation || operation.precedence > lastoperation.precedence) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; stack.push(operation.addInput(input))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; collapse(operation.precedence)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lastOperation.addInput(input);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; collapse(operation.precedence);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; wrapLastOperation(operation);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return this;&nbsp; &nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; &nbsp; &nbsp; openContext: function() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; error && reset();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var lastOperation = levels.peek().peek();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (closedContext || lastOperation && lastOperation.isSaturated()) return&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //Opening new context means creating a new level to the stack&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; levels.push(new Stack);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return this;&nbsp; &nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; &nbsp; &nbsp; closeContext: function(number) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; error && reset();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //If there's only one level, there's no need to close the context.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (levels.length <= 1) return;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var inpute = closedContext || number&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //Grab last used operation&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var stack = levels.peek();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var lastOperation = stack.peek()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; closedContext = new Operation(operationData.context).addInput(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lastOperation ? (function() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lastOperation.addInput(input);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; collapse(0);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return stack.pop();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }()) :&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; input&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; partialResult = Number(closedContext);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; levels.pop();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return this;&nbsp; &nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; &nbsp; &nbsp; evaluate: function(number) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; error && reset();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var input = closedContext || number&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //If no operator provided (just a number & '='), set result to the number.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; partialResult = Number(input);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //If '=' is used without closing all parenthases, close the context.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while (levels.length > 1) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.closeContext(input)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var lastOperation = levels.peek().peek();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lastOperation && lastOperation.addInput(input);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; collapse(0);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; reset();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return this;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; &nbsp; &nbsp; getPartialResult: function() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var _partialResult = partialResult;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; partialResult = 0;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return _partialResult&nbsp; &nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; &nbsp; &nbsp; getCalculationString: function(collapsed) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var result = closedContext ? closedContext.getCalculationString('', collapsed) : '';&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (var i = levels.length - 1; i >= 0; i--) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (var j = levels[i].length - 1; j >= 0; j--) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result = levels[i][j].getCalculationString(result, collapsed);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (i > 0) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result = '(' + result;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return result&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; })&nbsp; }&nbsp; //Build calculator interface&nbsp; //Prototype for adding buttons&nbsp; $.fn.addButton = function(html, className, onclick) {&nbsp; &nbsp; $('<button />', {&nbsp; &nbsp; &nbsp; html: html,&nbsp; &nbsp; &nbsp; 'class': 'button ' + className,&nbsp; &nbsp; &nbsp; click: onclick&nbsp; &nbsp; }).appendTo(this);&nbsp; &nbsp; return this;&nbsp; }&nbsp; var addNumberButton = function(num) {&nbsp; &nbsp; $numbers.addButton(num, 'number ' + (num === '.' ? 'dot' : 'number-' + num), () => {&nbsp; &nbsp; &nbsp; if ($input.text().match(/\./) && num == '.') return;&nbsp; &nbsp; &nbsp; if ($input.text() == 0 && num != '.' || $input.data('clearOnInput')) {&nbsp; &nbsp; &nbsp; &nbsp; $input.text('');&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; $input.data({&nbsp; &nbsp; &nbsp; &nbsp; clearOnInput: false&nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; $input.text($input.text() + $(this).text());&nbsp; &nbsp; })&nbsp; };&nbsp; var addOperatorButton = function(op, click) {&nbsp; &nbsp; $operators.addButton(op.buttonHTML, 'operator ' + op.name, function(e) {&nbsp; &nbsp; &nbsp; click.call(this, e);&nbsp; &nbsp; &nbsp; $currentCalc.text(inputStack.getCalculationString());&nbsp; &nbsp; &nbsp; $collapsedCalc.text(inputStack.getCalculationString(true));&nbsp; &nbsp; &nbsp; $input.text(inputStackgetPartialResult());&nbsp; &nbsp; &nbsp; $input.data({&nbsp; &nbsp; &nbsp; &nbsp; clearOnInput: true&nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; });&nbsp; };&nbsp; var getInput = () => {&nbsp; &nbsp; var input = $input.text();&nbsp; &nbsp; return input.match(/error/i) ? 0 : parseFloat($input.text())&nbsp; }&nbsp; var $calculator = $('#calculator');&nbsp; var $calcDisplay = $('<div/>', {&nbsp; &nbsp; 'class': 'calcDisplay'&nbsp; }).appendTo($calculator);&nbsp; var $currentCalc = $('<div/>', {&nbsp; &nbsp; 'class': 'currentCalc'&nbsp; }).appendTo($calcDisplay);&nbsp; var $collapsedCalc = $('<div/>', {&nbsp; &nbsp; 'class': 'collapsedCalc'&nbsp; }).appendTo($calcDisplay);&nbsp; var $input = $('<div/>', {&nbsp; &nbsp; 'class': 'input'&nbsp; }).appendTo($calcDisplay);&nbsp; var $numbers = $('<div/>', {&nbsp; &nbsp; 'class': 'numbers'&nbsp; }).appendTo($calculator);&nbsp; var $operators = $('<div/>', {&nbsp; &nbsp; 'class': 'operators'&nbsp; }).appendTo($calculator);&nbsp; $numbers.addButton('del', 'del', () => {&nbsp; &nbsp; $input.text($input.text().replace(/.$/, ''))&nbsp; })&nbsp; $numbers.addButton('CE', 'clear-entry', () => {&nbsp; &nbsp; $input.text('0')&nbsp; })&nbsp; $numbers.addButton('C', 'clear')&nbsp; $.each('7894561230.'.split(''), (itm, value) => {&nbsp; &nbsp; addNumberButton(value)&nbsp; });&nbsp; addOperatorButton({&nbsp; &nbsp; buttonHTML: '(',&nbsp; &nbsp; name: 'openContext'&nbsp; }, () => {&nbsp; &nbsp; inputStack.openContext();&nbsp; });&nbsp; addOperatorButton({&nbsp; &nbsp; buttonHTML: ')',&nbsp; &nbsp; name: 'closeContext'&nbsp; }, () => {&nbsp; &nbsp; inputStack.closeContext(getInput());&nbsp; });&nbsp; for (var i in opsData) {&nbsp; &nbsp; (function(i) {&nbsp; &nbsp; &nbsp; if (!opsData[i].buttonHTML) return;&nbsp; &nbsp; &nbsp; addOperatorButton(opsData[i], () => {&nbsp; &nbsp; &nbsp; &nbsp; inputStack.push(getInput(), new Operation(opsData[i]));&nbsp; &nbsp; &nbsp; })&nbsp; &nbsp; }(i))&nbsp; }&nbsp; addOperatorButton({&nbsp; &nbsp; buttonHTML: '=',&nbsp; &nbsp; name: 'evaluate'&nbsp; }, () => {&nbsp; &nbsp; inputStack.evaluate(getInput());&nbsp; });});html,body {&nbsp; background-color: black;}#calculator {&nbsp; background-color: grey;&nbsp; width: 250px;&nbsp; padding-top: 20px;&nbsp; padding-bottom: 30px;&nbsp; border-bottom-right-radius: 2em;&nbsp; border-bottom-left-radius: 2em;&nbsp; margin-right: auto;&nbsp; margin-left: auto;&nbsp; overflow: auto;}.calcDisplay {&nbsp; border: 1px solid;&nbsp; height: 50px;&nbsp; margin: 4px;&nbsp; padding: 2px;&nbsp; text-align: right;&nbsp; overflow: hide;&nbsp; position: relative;&nbsp; background: white;}.button {&nbsp; width: 60px;&nbsp; height: 60px;&nbsp; padding: 0px;&nbsp; line-height: 30px;&nbsp; text-align: center;&nbsp; border: 1px solid;&nbsp; cursor: pointer;&nbsp; float: left;&nbsp; margin: 4px;&nbsp; border-radius: 50%;}.number {&nbsp; background: #fff;}.number-0 {&nbsp; width: 129px;}<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script><div id='calculator'></div>

幕布斯6054654

问题是当您尝试循环遍历 opsData 对象时。for (var i in opsData) {&nbsp; (function(i) {&nbsp; &nbsp; if (!opsData.buttonHTML[i]) return;&nbsp; &nbsp; &nbsp; addOperatorButton(opsData[i], () => {&nbsp; &nbsp; &nbsp; inputStack.push(getInput(), new Operation(opsData[i]));&nbsp; &nbsp; })&nbsp; }(i))}当您应该访问 opsData[i].buttonHTML 时,您正在访问 buttonHTML 的 [i] 属性
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript