Hi guys,
Wondering if anyone can help explain to me why the javascript that I have written runs differently in the browser compared with CodePen?
Below is javascript for a calculator that works when running through CodePen. To make this same code work through the browser I have to:
- change let declarations of allButtons and calcScreen to var declarations
- remove let declarations of firstNumber, secondNumber, modValue, operator and previous key.
let allButtons = document.getElementsByClassName('button');
let calcScreen = document.getElementById('calc-screen');
let firstNumber = '';
let secondNumber = '';
let modValue = '';
let operator = '';
let previousKey = '';
function numberWithCommas(x) {
return x.toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ",");
}
function getKeyType(key) {
if (key >= 0) {
return 'number'
} else if (key == '/' || key == 'Ă—' || key == '-' || key == '+') {
return 'operator'
} else if (key == '=') {
return 'calculate'
} else if (key == '.') {
return 'decimal'
} else if (key == 'C') {
return 'clear'
} else if (key == '+/-') {
return 'positive/negative'
} else if (key == '%') {
return 'percentage'
}
}
function calculate(n1, op, n2) {
let firstNum = parseFloat(n1);
let secondNum = parseFloat(n2);
let result = '';
if (op === '+') {
result = (firstNum + secondNum).toLocaleString();
} else if (op === '-') {
result = (firstNum - secondNum).toLocaleString();
} else if (op === 'Ă—') {
result = (firstNum * secondNum).toLocaleString();
} else if (op === '/') {
result = (firstNum / secondNum).toLocaleString();
}
return (result.length > 14) ? secondNum.toLocaleString() : result
};
function createResultString(key, displayedNum, firstNumber, secondNumber, modValue, operator, previousKey) {
const keyType = getKeyType(key)
if (keyType == 'number') {
return (displayedNum.length < 14 || previousKey!= 'number')
? (displayedNum === 0 || previousKey != 'number')
? (previousKey == 'positive/negative') ? ('-' + key) : key
: numberWithCommas((displayedNum + key).replace(/,/g, ''))
: displayedNum
}
if (keyType == 'decimal') {
return (!displayedNum.includes('.'))
? (previousKey == 'operator') ? '0.' : displayedNum + '.'
: displayedNum
}
if (keyType == 'operator') {
secondNumber = displayedNum;
return (firstNumber && operator && previousKey != 'operator' && previousKey != 'calculate')
? calculate(firstNumber.replace(/,/g, ''), operator, secondNumber.replace(/,/g, ''))
: displayedNum
}
if (keyType == 'calculate') {
secondNumber = displayedNum;
return (firstNumber)
? (previousKey == 'calculate')
? calculate(displayedNum.replace(/,/g, ''), operator, modValue.replace(/,/g, ''))
: calculate(firstNumber.replace(/,/g, ''), operator, secondNumber.replace(/,/g, ''))
: displayedNum
}
if (keyType == 'clear') {
return '0';
}
if (keyType == 'positive/negative') {
if (previousKey == 'operator') {
return displayedNum;
} else if (displayedNum.includes('-')) {
return displayedNum.replace('-', '');
} else {
return '-' + displayedNum;
}
}
if (keyType == 'percentage') {
if (previousKey == 'number') {
return (operator == '+' || operator == '-')
? firstNumber * displayedNum / 100
: displayedNum / 100
} else {
return displayedNum
}
}
}
function updateState(key, displayedNum, calcValue) {
const keyType = getKeyType(key)
if (keyType == 'number') {
previousKey = keyType;
}
if (keyType == 'decimal') {
previousKey = 'number';
}
if (keyType == 'operator') {
(firstNumber && operator && previousKey != 'operator' && previousKey != 'calculate')
? firstNumber = calcValue.replace(/,/g, '')
: firstNumber = displayedNum.replace(/,/g, '')
operator = key;
previousKey = keyType;
}
if (keyType == 'calculate') {
secondNumber = displayedNum.replace(/,/g, '');
if (firstNumber) {
if (previousKey == 'calculate') {
secondNumber = modValue;
}
}
modValue = secondNumber;
previousKey = keyType;
}
if (keyType == 'clear') {
firstNumber = '';
secondNumber = '';
operator = '';
previousKey = '';
}
if (keyType == 'positive/negative') {
previousKey = keyType;
}
if (keyType == 'percentage') {
if (previousKey == 'number') {
return (operator == '+' || operator == '-')
? secondNumber = firstNumber * displayedNum / 100
: secondNumber = displayedNum / 100
} else {
firstNumber = displayedNum / 100;
}
previousKey = keyType;
}
}
function calcScreenSize(screenContent) {
if (screenContent.length > 9) {
calcScreen.style.fontSize = '34px';
} else {
calcScreen.style.fontSize = '50px';
}
}
for (var i=0; i<allButtons.length; i++) {
allButtons[i].addEventListener('click', function() {
const key = this.textContent;
const displayedNum = calcScreen.textContent;
// pure function
const resultString = createResultString(key, displayedNum, firstNumber, secondNumber, modValue, operator, previousKey);
// update states
calcScreen.textContent = resultString;
calcScreenSize(resultString);
updateState(key, displayedNum, resultString);
});
};