The front end uses JavaScript to implement a simple calculator, no difficulty, but there are some small knowledge or need to pay attention to, it is a basic knowledge review.

The title

To implement a simple version of the calculator, the requirements are as follows:

2. If the result is a decimal, keep at most two decimal places after the decimal point. For example, 2/3 = 0.67(0.67 displayed), 1/2 = 0.5(0.5 displayed) 3. Read and complete initEvent, result, and Calculate functions as prompted 4. Do not manually modify HTML and CSS 5

implementation

The HTML file

<div class="calculator">
    <header class="cal-header">Simple calculator</header>
    <main class="cal-main">
        <div class="origin-value">0</div>
        <div class="cal-keyboard">
            <ul class="cal-items">
                <li data-action="num">7</li>
                <li data-action="num">8</li>
                <li data-action="num">9</li>
                <li data-action="operator">present</li>
                <li data-action="num">4</li>
                <li data-action="num">5</li>
                <li data-action="num">6</li>
                <li data-action="operator">x</li>
                <li data-action="num">1</li>
                <li data-action="num">2</li>
                <li data-action="num">3</li>
                <li data-action="operator">-</li>
                <li data-action="num">0</li>
                <li data-action="operator">empty</li>
                <li data-action="operator">=</li>
                <li data-action="operator">+</li>
            </ul>
        </div>
    </main>
</div>
Copy the code

The CSS file

body.ul.li,select {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}
ul.li {list-style: none; }.calculator {
    max-width: 300px;
    margin: 20px auto;
    border: 1px solid #eee;
    border-radius: 3px;
}
.cal-header {
    font-size: 16px;
    color: # 333;
    font-weight: bold;
    height: 48px;
    line-height: 48px;
    border-bottom: 1px solid #eee;
    text-align: center;
}
.cal-main {
    font-size: 14px;
}
.cal-main .origin-value {
    padding: 15px;
    height: 40px;
    line-height: 40px;
    font-size: 20px;
    text-align: right;
    overflow: hidden;
    text-overflow:ellipsis;
    white-space: nowrap;
}
.cal-main .origin-type..cal-main .target-type {
    padding-left: 5px;
    width: 70px;
    font-size: 14px;
    height: 30px;
    border: 1px solid #eee;
    background-color: #fff;
    vertical-align: middle;
    margin-right: 10px;
    border-radius: 3px;
}
.cal-keyboard {
    overflow: hidden;
}
.cal-items {
    overflow: hidden;
}
.cal-items li {
    user-select: none;
    float: left;
    display: inline-block;
    width: 75px;
    height: 75px;
    text-align: center;
    line-height: 75px;
    border-top: 1px solid #eee;
    border-left: 1px solid #eee;
    box-sizing: border-box;
}
li:nth-of-type(4n+1) {
    border-left: none;
}
li[data-action=operator] {
    background: #f5923e;
    color: #fff;
}
.buttons {
    float: left;
    width: 75px;
}
.buttons .btn {
    width: 75px;
    background-color: #fff;
    border-top: 1px solid #eee;
    border-left: 1px solid #eee;
    height: 150px;
    line-height: 150px;
    text-align: center;
}
.btn-esc {
    color: #ff5a34;
}
.btn-backspace {
    position: relative;
}
Copy the code

JavaScript files

var Calculator = {
    init: function () {
        var that = this;
        if(! that.isInited) { that.isInited =true;
            // Save the operation information
            // total: Number
            // Next: String, the next data to be evaluated with total
            // action: String
            that.data = {total: 0.next: ' '.action: ' '}; that.bindEvent(); }},bindEvent: function () {
        var that = this;
        // Get the.cal-keyboard element
        var keyboardEl = document.querySelector(".cal-keyboard");
        keyboardEl && keyboardEl.addEventListener('click'.function (event) {
            // Get the currently clicked DOM element
            var target = event.target;
            // Get the data-action value for target
            var action = target.dataset.action;
            // Get the contents of target
            var value = target.innerText;
            if (action === 'num' || action === 'operator') {
                that.result(value, action === 'num'); }}); },result: function (action, isNum) {
        var that = this;
        var data = that.data;
        if (isNum) {
            data.next = data.next === '0'? action : (data.next + action); ! data.action && (data.total =0);
        } else if (action === 'empty') {
            // Set the corresponding state when clearing
            data.total = 0;
            data.next = "";
            data.action = "";
        } else if (action === '=') {
            if (data.next || data.action) {
                data.total = that.calculate(data.total, data.next, data.action);
                data.next = ' ';
                data.action = ' '; }}else if(! data.next) { data.action = action; }else if (data.action) {
            data.total = that.calculate(data.total, data.next, data.action);
            data.next = ' ';
            data.action = action;
        } else {
            data.total = +data.next || 0;
            data.next = ' ';
            data.action = action;
        }

        // Get the.origin-value element
        var valEl = document.querySelector(".origin-value");
        // print(data)
        valEl && (valEl.innerHTML = data.next || data.total || '0');
    },
    calculate: function (n1, n2, operator) {
        n1 = +n1 || 0;
        n2 = +n2 || 0;
        if (operator === 'present') {
            // Get the result of division
            return n2 === 0 ? 0 : Math.floor((n1 / n2) * 100) / 100;
        } else if (operator === 'x') {
            // Get the result of multiplication
            return Math.floor((n1 * n2) * 100) / 100;
        } else if (operator === '+') {
            // Get the result of the addition
            return Math.floor((n1 + n2) * 100) / 100;
        } else if (operator === The '-') {
            // get the result of subtraction
            return Math.floor((n1 - n2) * 100) / 100; }}}; Calculator.init();Copy the code

Analysis of the

Let’s focus on the JavaScript part of this topic.

Event delegation

Instead of adding click events to numeric and symbolic elements, we add click events to their parent element. Cal-keyboard, and then get the event response bound to its parent element by bubbling through the event. Using event delegates has the following advantages:

  • Reduce memory consumption
  • You can easily add or remove elements dynamically
  • Fewer functions to manage
  • Reduce the number of DOM node operations to improve performance

Steps for event delegation:

  1. Bind the response event to the parent element
  2. Listen for bubbling events on child elements
  3. Gets the target element that triggers the event

Reserved decimal place

Your first instinct may be to use the toFixed() method, but this method will fill in zeros if the number of decimal places is insufficient, as in:

const num = 0.8;
num.toFixed(2) / / 0.80
Copy the code

As you can see, this doesn’t meet the requirements.

One more thing to note: decimals may not add up as expected, for example:

console.log(0.2 + 0.4) / / 0.6000000000000001
Copy the code

Here we recommend using the math.floor () method to deal with decimal places. Multiply the result by 100, get the integer part by math.floor (), and divide by 100 to get the desired result, such as:

const num1 = 0.5;
const num2 = 0.68751;
Math.floor(num1 * 100) /100   	/ / 0.5
Math.floor(num2 * 100) /100		/ / 0.68
Copy the code

~

To finish this article

~

Learn interesting knowledge, meet interesting friends, shape interesting soul!

Hello everyone, I am the author of “programming Samadhi”, I am king Yi, my public account is “programming Samadhi”, welcome to pay attention, I hope you can give me more advice!

You come, with expectations, I have ink to welcome! You return, no matter gain or loss, only to yu Yun give each other!

Knowledge and skills should be paid equal attention to, internal force and external power should be repaired simultaneously, theory and practice should grasp both hands, both hands should be hard!