NỘI DUNG BÀI VIẾT
Ứng dụng máy tính đơn giản
Bài viết này sẽ hướng dẫn chi tiết cách xây dựng một ứng dụng máy tính đơn giản bằng JavaScript. Đến cuối bài viết, bạn sẽ xây dựng được một máy tính có chức năng gần giống như máy tính trên iPhone.
HTML
Đầu tiên, bạn phải xây dựng máy tính bằng HTML và CSS.
Máy tính bao gồm hai phần: display (màn hình) và keys (các phím)
<div class="calculator">
<div class="calculator__display">0</div>
<div class="calculator__keys">
<button class="key--operator" data-action="add">+</button>
<button class="key--operator" data-action="subtract">-</button>
<button class="key--operator" data-action="multiply">×</button>
<button class="key--operator" data-action="divide">÷</button>
<button>7</button>
<button>8</button>
<button>9</button>
<button class="key--equal" data-action="calculate">=</button>
<button>5</button>
<button>6</button>
<button>4</button>
<button>1</button>
<button>2</button>
<button>3</button>
<button>0</button>
<button data-action="decimal">.</button>
<button data-action="clear">AC</button>
</div>
</div>
Code language: HTML, XML (xml)
nhận sự kiện ấn phím từ người dùng.
Các thao tác cơ bản của người dùng khi sử dụng calculator:
- Một phím số (0 ~ 9) (number key)
- Một phím toán tử (+, -, ×, ÷) (operator key)
- Phím thập phân (decimal key)
- Phím bằng (equals key)
- Phím khởi tạo (clear key)
Các bước đầu tiên để xây dựng máy tính này là có thể (1) nhận sự kiện tất cả các phím bấm và (2) xác định loại phím được nhấn. Trong trường hợp này, chúng ta có thể sử dụng event delegation pattern trong JavaScript, vì các khóa đều là con của .calculator__keys.
JavaScript
const calculator = document.querySelector('.calculator');
const keys = calculator.querySelector('.calculator__keys');
keys.addEventListener('click', e => {
if (e.target.matches('button')) {
// Do something
}
})
Code language: JavaScript (javascript)
Tiếp theo, chúng ta có thể sử dụng thuộc tính data-action để xác định loại khóa được nhấn.
const key = e.target;
const action = key.dataset.action;
Code language: JavaScript (javascript)
Nếu khóa không có thuộc tính data-action, nó phải là khóa số.
if (!action) {
console.log('number key!');
}
Code language: JavaScript (javascript)
Nếu khóa có data-action là add, subtract, multiple hoặc divide, chúng ta biết khóa là toán tử.
if (
action === 'add' ||
action === 'subtract' ||
action === 'multiply' ||
action === 'divide'
) {
console.log('operator key!')
}
Code language: JavaScript (javascript)
Nếu data-action là decimal, chúng ta biết người dùng đã nhấp vào decimal key. Tương tự cho các khóa equal và clear.
if (action === 'decimal') {
console.log('decimal key!')
}
if (action === 'clear') {
console.log('clear key!')
}
if (action === 'calculate') {
console.log('equal key!')
}
Code language: JavaScript (javascript)
Khi người dùng nhấn number key
Tại thời điểm này, nếu máy tính hiển thị 0 (số mặc định), khi người dùng ấn phím từ không đến 9 thì số 0 sẽ bị thay thế.
Nếu máy tính hiển thị số khác 0, số được nhấn sẽ được thêm vào số hiển thị.
Ta phải xác định được 2 thứ:
- Số lượng phím được nhấp
- Số hiển thị hiện tại
Ta có thể nhận được hai giá trị này thông qua thuộc tính textContent của khóa được:
const display = document.querySelector('.calculator__display')
keys.addEventListener('click', e => {
if (e.target.matches('button')) {
const key = e.target
const action = key.dataset.action
const keyContent = key.textContent
const displayedNum = display.textContent
// ...
}
})
Code language: JavaScript (javascript)
Nếu máy tính hiển thị 0, thì thay thế màn hình máy tính bằng phím bấm. Ta có thể làm vậy bằng cách dùng thuộc tính textContent
if (!action) {
if (displayedNum === '0') {
display.textContent = keyContent
}
}
Code language: JavaScript (javascript)
Nếu máy tính hiển thị số khác không, thì nối thêm phím đã nhấn vào số được hiển thị.
if (!action) {
if (displayedNum === '0') {
display.textContent = keyContent
} else {
display.textContent = displayedNum + keyContent
}
}
Code language: JavaScript (javascript)
Khi người dùng nhấn decimal key
Khi người dùng nhấn decimal key, một số thập phân sẽ được thêm vào màn hình. Nếu người dùng nhấn bất kỳ số nào sau khi nhấn decimal key, số đó cũng sẽ được thêm vào màn hình.
if (action === 'decimal') {
display.textContent = displayedNum + '.'
}
Code language: JavaScript (javascript)
Khi người dùng nhấn operator key
Ta thêm class ‘is-depressed’ để nhận biết người dùng đang nhấn operator key
if (
action === 'add' ||
action === 'subtract' ||
action === 'multiply' ||
action === 'divide'
) {
key.classList.add('is-depressed')
}
Code language: JavaScript (javascript)
Khi người dùng nhấn phím number key sau phím operator key
Màn hình trước đó sẽ được thay thế bằng số mới. operator key cũng phải được xóa bỏ class ‘is-depressed’.
keys.addEventListener('click', e => {
if (e.target.matches('button')) {
const key = e.target
// ...
// Remove .is-depressed class from all keys
Array.from(key.parentNode.children)
.forEach(k => k.classList.remove('is-depressed'));
}
})
Code language: PHP (php)
Tiếp theo, ta muốn cập nhật màn hình bằng phím được nhấn. Trước khi thực hiện việc này, ta cần phải biết liệu khóa trước có phải là operator key hay không bằng cách sử dụng thuộc tính data-previous-key-type.
const calculator = document.querySelector('.calculator')
// ...
keys.addEventListener('click', e => {
if (e.target.matches('button')) {
// ...
if (
action === 'add' ||
action === 'subtract' ||
action === 'multiply' ||
action === 'divide'
) {
key.classList.add('is-depressed')
// Add custom attribute
calculator.dataset.previousKeyType = 'operator'
}
}
})
Code language: JavaScript (javascript)
Nếu previousKeyType là một operator, ta sẽ thay thế màn hình hiển thị bằng số đã nhấn.
if (displayedNum === '0' || calculator.dataset.previousKeyType === 'operator') {
display.textContent = keyContent;
calculator.dataset.previousKeyType= "";
} else {
display.textContent = displayedNum + keyContent;
calculator.dataset.previousKeyType= "";
}
Code language: JavaScript (javascript)
Khi người dùng nhấn equals key, máy tính sẽ tính kết quả phụ thuộc vào ba giá trị:
- Số đầu tiên được nhập vào
- Operator key
- Số thứ hai được nhập
Sau khi tính toán, kết quả sẽ thay thế ở màn hình hiển thị.
Để có được số đầu tiên, ta cần lưu trữ giá trị hiển thị của máy tính trước khi xóa.
Để có được toán tử, chúng ta cũng có thể sử dụng phương pháp tương tự.
if (
action === 'add' ||
action === 'subtract' ||
action === 'multiply' ||
action === 'divide'
) {
// ...
calculator.dataset.firstValue = displayedNum;
calculator.dataset.operator = action;
}
Code language: JavaScript (javascript)
Sau đó bắt đầu thực hiện phép tính.
if (action === 'calculate') {
const firstValue = calculator.dataset.firstValue
const operator = calculator.dataset.operator
const secondValue = displayedNum
display.textContent = calculate(firstValue, operator, secondValue)
}
Code language: JavaScript (javascript)
Chúng ta có function calculate:
function calculate(firstNum,operator,secondNum){
if(operator === 'add'){
return parseFloat(firstNum) +parseFloat(secondNum) ;
}
if(operator === 'subtract'){
return parseFloat(firstNum) -parseFloat(secondNum) ;
}
if(operator === 'multiply'){
return parseFloat(firstNum) *parseFloat(secondNum) ;
}
if(operator === 'divide'){
return parseFloat(firstNum) /parseFloat(secondNum) ;
}
}
Code language: JavaScript (javascript)
Ta phải chỉnh sửa decimal key. Chỉ thêm 1 decimal key vào số hiển thị.
if (action === 'decimal') {
console.log('decimal key!');
if (!displayedNum.includes('.')){
display.textContent = displayedNum + '.';
}
}
Code language: JavaScript (javascript)
Tiếp theo, nếu người dùng nhấn decimal key sau khi nhấn operator key, màn hình sẽ hiển thị 0.
Gán giá trị cho previousKey.
if (!action) {
// ...
calculator.dataset.previousKeyType = 'number'
}
if (action === 'decimal') {
// ...
if (!displayedNum.includes('.') && calculator.dataset.previousKeyType != ‘operator’) {
display.textContent = displayedNum + '.'
} else if (previousKeyType === 'operator') {
display.textContent = '0.'
}
calculator.dataset.previousKeyType = 'decimal'
}
if (action === 'clear') {
// ...
calculator.dataset.previousKeyType = 'clear'
}
if (action === 'calculate') {
// ...
calculator.dataset.previousKeyType = 'calculate'
}
Code language: JavaScript (javascript)
Chúng ta phải chỉnh sửa calculate key để hoàn thiện ứng dụng này. Chỉ tính toán khi giá trị firstValue và operator khác undefine:
if (action === 'calculate') {
console.log('equal key!');
const firstValue = calculator.dataset.firstValue;
const operator = calculator.dataset.operator;
const secondValue = displayedNum;
if(firstValue!= undefined && operator !=undefined){
display.textContent = calculate(firstValue, operator, secondValue);
calculator.dataset.previousKeyType = 'calculate';
}
}
Code language: JavaScript (javascript)
Tới đây, chúng ta đã hoàn thành xong ứng dụng máy tính đơn giản bằng JavaScript.
Bạn có thể download file Full-Code tại đây.
Vì ứng dụng còn nhiều chức năng chưa được làm, bạn hãy tự phát triển và xây dựng chúng theo cách của bạn mong muốn.
Chúc các bạn thành công!
Các bạn có thể tham khảo các bài viết hay về JavaScript tại đây.
Hãy tham gia nhóm Học lập trình để thảo luận thêm về các vấn đề cùng quan tâm.