js 设置password placeholder样式_Vue.js 实现计算器

d494238db4a01969da997ca8adc01fad.png

实现了一个简单的计算器,使用了 Grid 布局,使用了事件委托来分别处理不同按钮的点击,使用了 Vue.js 框架,使用了栈数据结构来处理十进制转二进制的运算,使用了递归来处理先乘除后加减的运算,然后通过条件判断来处理所有情况。

写代码的顺序是这样的:先写 HTML 结构,再写 CSS 样式,再写 JS 逻辑代码,写逻辑代码时先将核心算法写出来,即加减乘除和进制转换算法,并处理细节部分,再将其他的按钮逻辑写出来,并处理细节部分。

这是 parse.js 文件,专门处理加减乘除算法,使用了递归

function parse(content) {
  var index = content.indexOf("+");
  //只要还有加号就还在这个判断句中进行逐层递归
  if(index > -1) {
    return parse(content.substring(0,index)) + parse(content.substring(index+1));
  }
  //当在表达式没有发现加号时,会到这里,递归就是层层递进,再将结果逐层回溯
  index = content.lastIndexOf("-");
  if(index > -1) {
    return parse(content.substring(0,index)) - parse(content.substring(index+1));
  }
  //要先放置加减再放置乘除,这样才会先乘除后加减
  index = content.indexOf("*");
  if(index > -1) {
    return parse(content.substring(0,index)) * parse(content.substring(index+1));
  }

  index = content.lastIndexOf("/")
  if(index > -1) {
    return parse(content.substring(0,index)) / parse(content.substring(index+1));
  }
  //递归的基准条件
  return Number(content);
}

这是 binary.js 文件,专门处理十进制转二进制算法,使用了栈数据结构

let Stack = (function() {
            const items = new WeakMap();
            class Stack {
               constructor() {
                  items.set(this, []);
               }
               push(element) {
                  let s=items.get(this);
                  s.push(element);
               }
               pop() {
                  let s=items.get(this);
                  return s.pop();
               }
               peek() {
                  let s=items.get(this);
                  return s[s.length-1];
               }
               isEmpty() {
                  let s=items.get(this);
                  return s.length == 0;
               }
               clear() {
                  let s=items.get(this);
                  s=[];
               }
               size() {
                  let s=items.get(this);
                  return s.length;
               }
            }
            return Stack;
         })();

         function divideBy2(decNumber) {
            var remStack=new Stack();
            var rem;
            var binaryString='';

            while (decNumber>0) {
               rem=Math.floor(decNumber%2);
               remStack.push(rem);
               decNumber=Math.floor(decNumber/2);
            }

            while (!remStack.isEmpty()) {
               binaryString += remStack.pop().toString();;
            }

            return binaryString;
         }

这是主代码:

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>A Simple Calculator</title>
    <style media="screen">
      html * {
        margin: 0;
        padding: 0;
      }
      .calculator {
        width: 200px;
        margin: 100px auto;
      }
      .calculator input {
        box-sizing: border-box;
        padding: 0 6px;
        background: #ccc;
        width: 200px;
        height: 50px;
        font-size: 32px;
        color: #FFF;
        text-align: right;
        outline: none;
        /* 让字体缩进,往左缩进200像素 */
        text-indent: -200px;
      }

      /* 处理 placeholder 的颜色 */
      ::-webkit-input-placeholder { /* WebKit, Blink, Edge */
        color: #FFF;
      }
      :-moz-placeholder { /* Mozilla Firefox 4 to 18 */
        color: #FFF;
      }
      ::-moz-placeholder { /* Mozilla Firefox 19+ */
        color: #FFF;
      }
      :-ms-input-placeholder { /* Internet Explorer 10-11 */
        color: #FFF;
      }

      /* 使用 Grid 布局 */
      .calculator .container {
        display: grid;
        width: 50%;
        grid-template-columns: repeat(4, 50px);
        grid-template-rows: repeat(4, 50px);
      }
      .item {
        color: #FFF;
        font-size: 32px;
        text-align: center;
        background: #CCC;
        border: 1px solid #BBB;
        outline: none;
      }
      .item-17 {
        grid-column-start: span 2;
      }

    </style>
  </head>
  <body>
    <section id="root" class="calculator">
      <input type="text" v-model="inputValue" placeholder="0" disabled="disabled" ref="one">
      <!-- 使用事件委托分别处理子元素的点击事件 -->
      <div class="container" @click="handleBtnClick">
        <button class="item item-1">AC</button>
        <button class="item item-2">C</button>
        <button class="item item-3">二</button>
        <button class="item item-4">/</button>
        <button class="item item-5">7</button>
        <button class="item item-6">8</button>
        <button class="item item-7">9</button>
        <button class="item item-8">*</button>
        <button class="item item-9">4</button>
        <button class="item item-10">5</button>
        <button class="item item-11">6</button>
        <button class="item item-12">-</button>
        <button class="item item-13">1</button>
        <button class="item item-14">2</button>
        <button class="item item-15">3</button>
        <button class="item item-16">+</button>
        <button class="item item-17">0</button>
        <button class="item item-18">.</button>
        <button class="item item-19">=</button>
      </div>
    </section>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
    <script src="./parse.js"></script>
    <script src="./binary.js"></script>
    <script>
      var vm = new Vue({
        el: '#root',
        data: {
          inputValue: '',
          content: '',
          lastBtn: [],
          record: false,
          cookies: [],
          case: false,
          n: 0
        },
        methods: {
          handleBtnClick(e) {
            var id = e.target.innerHTML
            //当点击数字按钮或者加减乘除运算符按钮时,将 id 逐一拼接在 content 中
            //当连续点击加减乘除运算符按钮时,将第二次的 id 覆盖掉第一次的 id
            //为了验证上一次的 id 和这一次的 id 是否都是加减乘除运算符,我们将每一次点击的 id 都通过 record 布尔值记录在 lastBtn 中,只有当 id 为加减乘除运算符时,将 record 设置成 true
            if(id === "+" || id === "-" || id === "*" || id === "/") {
              this.record = true
              if(!this.content) {
                this.content = "0"
                this.inputValue = this.content
              }
            }

            this.lastBtn.push(this.record)
            if(this.record) this.record = false

            if(!isNaN(id) || id === "+" || id === "-" || id === "*" || id === "/") {
              if(this.lastBtn[this.lastBtn.length-2] && this.lastBtn[this.lastBtn.length-1]) {
                this.content = this.content.substring(0,this.content.length-1)
              }
              this.content += id
              this.inputValue = this.content
            }

            //按等于号时,将结果显示出来,并将结果缓存起来
            if(id === "=") {
              this.inputValue = parse(this.content) + ""
              this.cookies.push(this.inputValue)
              this.case = true
              //我们只需要记录上一次的 id
              this.lastBtn = this.lastBtn.splice(this.lastBtn.length-1,1)
            }

            //当计算过一次结果后
            if(this.case) {
              //如果直接点击加减乘除运算符,将 content 清空,并且将结果赋值给 content
              if(id === "+" || id === "-" || id === "*" || id === "/") {
                this.content = this.cookies[this.cookies.length-1] + id
                this.inputValue = this.content
                this.case = false
              }
              //如果直接点击数字按钮,就是新的一轮运算
              if(!isNaN(id)) {
                this.content = id
                this.inputValue = this.content
                this.case = false
              }
              //如果直接点击小数点,就是新的一轮运算
              if(id === ".") {
                this.content = "0."
                this.inputValue = this.content
                this.case = false
              }
            }

            //当点击 "." 时,总体上分为 content 不为空和为空两种情况分别怎么处理
            //当 content 不为空时,有三种情况分别怎么处理
            if(id === ".") {
              if(this.content) {
                if(!isNaN(this.content) && this.content.indexOf(".") === -1) {
                  this.content += id
                  this.inputValue = this.content
                }else if(isNaN(this.content) && this.lastBtn[this.lastBtn.length-2]) {
                  this.content += "0."
                  this.inputValue = this.content
                }else if(isNaN(this.content) && !this.lastBtn[this.lastBtn.length-2]){
                  //取 content 最后一个数字或者小数
                  var re1 = /d+(.d+)?$/
                  var lastNum1 = this.content.match(re1)
                  if(lastNum1[0].indexOf(".") === -1) {
                    this.content += id
                    this.inputValue = this.content
                  }
                }
              }else {
                this.content = "0."
                this.inputValue = this.content
              }
            }

            //在输入数字按钮时,不能出现 0 打头的正整数
            if(!isNaN(id)) {
              if(!isNaN(this.content)) {
                var re = /^[0]d/
                if(re.test(this.content)) {
                  this.content = this.content.substring(1)
                  this.inputValue = this.content
                }
              }else {
                //取 content 最后一个数字或者小数
                var re = /d+(.d+)?$/
                var lastNum = this.content.match(re)
                var index = lastNum.index
                //只有整数才能进入到下面条件句中,会忽略小数
                re = /^[0]d/
                if(re.test(lastNum[0])) {
                  this.content = this.content.substring(0,index) + this.content.substring(index+1)
                  this.inputValue = this.content
                }
              }
            }

            //当点击 "二" 时,可以将十进制转换成二进制
            if(id === "二") {
              if(!isNaN(this.inputValue))
                this.inputValue = divideBy2(this.inputValue)
            }

            //当点击 "AC" 时,初始化所有数据
            if(id === "AC") {
              this.inputValue = ""
              this.content = ""
              this.lastBtn = []
              this.cookies = []
              this.case = false
              this.$refs.one.style.fontSize = "32px"
            }

            //当点击 "C" 时,可以逐一删除信息
            if(id === "C") {
              this.content = this.content.substring(0,this.content.length-1)
              this.inputValue = this.content
            }
          }
        },
        //使字体大小随着字符数量的增加而缩小,当缩小到一定范围后,就不再缩小,而是往左缩进 200 像素
        watch: {
          inputValue() {
            this.n = this.inputValue.length
            if(this.n > 10 && this.n < 27){
              this.$refs.one.style.fontSize = 308/this.n + "px"
            }else if(this.n <= 10){
              this.$refs.one.style.fontSize = "32px"
            }
          }
        }
      })
    </script>
  </body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值