利用面向对象方式实现js计算器

利用ES5原型编程的方式实现js计算器

后面代码更新都会放在我的 GitHub 求个star

<!DOCTYPE html>
<html lang="">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Calculator</title>
    <link rel="stylesheet" href="./css/calculator.css">
</head>
<body>
    <div id="calculator">
        <!-- 显示计算过程与结果的盒子 -->
        <div class="show_box">
            <!-- 结果 -->
            <div class="result">
                <span></span>
            </div>
            <!-- 过程 -->
            <div class="show">
                <span></span>
            </div>
        </div>
        <!-- 输入按钮 -->
        <div class="inputtedBtns">
            <ul>
                <li>7</li>
                <li>8</li>
                <li>9</li>
                <li>/</li>
            </ul>
            <ul>
                <li>4</li>
                <li>5</li>
                <li>6</li>
                <li>*</li>
            </ul>
            <ul>
                <li>1</li>
                <li>2</li>
                <li>3</li>
                <li>+</li>
            </ul>
            <ul>
                <li>0</li>
                <li id="clean">c</li>
                <li>.</li>
                <li>-</li>
            </ul>
            <!-- 等于按钮 -->
            <button class="equals_btn">=</button>
        </div>
    </div>
    <script src="./js/calculator.js"></script>
    <script>
        new Calculator().init();
    </script>
</body>
</html>
*{
  margin: 0;
  padding: 0;
}
ul{
  list-style: none;
}
body{
  background-color: #34495e;
}
#calculator{
  width: 330px;
  height: 480px;
  margin: 100px auto;
}
#calculator span{
  display: inline-block;
  font-size: 32px;
}
#calculator .show_box{
  background-color: #fff;
  height: 150px;
  border-top-left-radius: 5px;
  border-top-right-radius: 5px;
  display: flex;
  flex-direction: column;
}
#calculator .show_box .result,#calculator .show_box .show{
  text-align: right;
  height: 50%;
  margin: 15px;
  overflow: hidden;
}
#calculator .show_box .result{
  color: salmon;
}

#calculator .inputtedBtns{
  position: relative;
  cursor: pointer;
  border-bottom-left-radius: 5px;
  border-bottom-right-radius: 5px;
  width: 330px;
  height: 330px;
  color: #657b8f;
  font-size: 25px;
  text-align: center;
  display: flex;
  flex-direction: column;
  flex-grow: 1;
  background: linear-gradient(to bottom,#e6f5ff 1%,#fff 8%);
  /* 设置文本不能选中 */
  user-select: none;
} 
#calculator .inputtedBtns ul{
  display: flex;
  flex-grow: 1;
  font-size: 25px;
}
#calculator .inputtedBtns li{
  width: 25%;
  line-height: calc(320px/4);
}
#calculator .inputtedBtns ul li:last-of-type{
  color: #58b3ff;
}
#calculator .inputtedBtns ul:last-of-type #clean{
  color: #ED4C67;
}
#calculator .inputtedBtns ul:last-of-type li:nth-child(3){
  line-height: 70px;
  color: #58b3ff;
}
#calculator .equals_btn{
  width: 150px;
  height: 40px;
  border-radius: 5px;
  border: none;
  background-color: #58b3ff;
  color: #fff;
  font-size: 30px;
  outline: none;
  position: absolute;
  right: 50%;
  bottom: -30px;
  transform: translateX(50%);
}
;(function (doc) {
  function Calculator() {
      //显示计算过程与结果的盒子
      this.showBox = doc.getElementsByClassName('show_box')[0];
      // 输入按钮
      this.inputtedBtns = doc.getElementsByClassName('inputtedBtns')[0];
      this.equalsBtn = doc.getElementsByClassName('equals_btn')[0];
      this.result = this.showBox.querySelector('.result');
      this.resultChild = this.result.querySelector('span');
      this.show = this.showBox.querySelector('.show');
      this.showChild = this.show.querySelector('span');
      this.clean = this.inputtedBtns.querySelector('#clean');
      this.ul = this.inputtedBtns.querySelector('ul');
      this.fontSizeUl = parseInt(window.getComputedStyle(this.ul).fontSize);
      this.flag = true;
  }
  //初始化方法
  Calculator.prototype.init = function () {
      this.BindEvent();
  }
  //事件方法
  Calculator.prototype.BindEvent = function () {
      this.inputtedBtns.addEventListener('click', this.onClickObtain.bind(this), false);
      this.equalsBtn.addEventListener('click', this.onClickResult.bind(this));
      this.clean.addEventListener('click', this.onClickClean.bind(this))
  }
  //利用事件委托,获取点击元素(关于事件委托:https://blog.csdn.net/m0_46217225/article/details/115328572?spm=1001.2014.3001.5501)
  Calculator.prototype.onClickObtain = function (e) {
      let elemLi = e.target;
      //调用字体变化动画方法
      Calculator.sizeAnimation(elemLi, this.fontSizeUl);
      //调用溢出处理方法
      if(this.showChild.clientWidth >= this.show.clientWidth && this.flag){
          Calculator.valOverflow(this.show);
          this.flag = false;
      }
      if (elemLi.tagName.toLowerCase() === 'li' && elemLi.id != "clean") {
          this.displayProcess(elemLi.innerText);
      }
  }
  //字体变化动画方法(这里造成了回调地狱,可以使用promise来改写)
  Calculator.sizeAnimation = function (elem, size) {
      let raise = setInterval(() => {
          elem.style.fontSize = size + 1 + 'px'
          size++;
          if (size >= 34) {
              clearInterval(raise);
              let decline = setInterval(() => {
                  elem.style.fontSize = size - 1 + 'px';
                  size--;
                  if (size <= 25) {
                      elem.style.fontSize = 25 + 'px';
                      clearInterval(decline);
                  }
              }, 15);
          }
      }, 15);
  }
  // 显示计算过程
  Calculator.prototype.displayProcess = function (elem) {
      this.showChild.innerText += elem;
  }
  //点击出结果
  Calculator.prototype.onClickResult = function () {
      if (this.showChild.innerHTML != "") {
          this.resultChild.style.fontSize = this.showChild.style.fontSize;
          this.resultChild.innerHTML = eval(this.show.innerText);
      }
  }
  //点击清除
  Calculator.prototype.onClickClean = function () {
      //清除子元素
      let showChild = this.showChild;
      showChild.innerText = "";
      showChild.style.fontSize = '32px'
      this.flag = true;
      //清除结果
      this.resultChild.innerText = "";
  }
  //数值溢出处理
  Calculator.valOverflow = function (elem) {
      //设置观察者的选项,需要观察的 变化(观察目标节点的子节点的新增和删除)
      let config = { childList: true, subtree: true }
      //设置观察者的回调函数
      function callback(records) {//记录变化的数组
          let rs = records[0].target;
          if (rs.clientWidth > rs.parentNode.clientWidth) {   
              rs.style.fontSize = parseInt(window.getComputedStyle(rs).fontSize) - 5 + 'px';
              //清楚突变观察者
              if(parseInt(elem.children[0].style.fontSize) <= 12){
                  observer.disconnect();
              }
          }
      }
      //创建突变观察者MutationObserver的实例对象
      let observer = new MutationObserver(callback);
      //添加需要观察的 元素 和 变化
      observer.observe(elem, config);
  }
  window.Calculator = Calculator;
})(document);
感兴趣还可以关注我的:

cnsd:m0_46217225

掘金:寸头男生

github:Buzz_cut

微信公众号:web_mycode

知乎:寸头男生

欢迎加入QQ群交流编程知识:

qq群:808752665

我的QQ:2356924146

我会持续分享编程干货。

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值