2021-01-09计算器

正文

html代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

<div class="errorHint" id="errorHint"></div>

    <table cellpadding="0">

        <tr>

            <th colspan="5">计算器</th>

        </tr>

        <tr>

            <td colspan="5">

                <input type="text" value="0" name="showResult">

            </td>

        </tr>

        <tr>

            <td><button>7</button></td>

            <td><button>8</button></td>

            <td><button>9</button></td>

            <td><button class="setChange" id="backSpace">退格</button></td>

            <td><button class="setChange" id="clearNum">C</button></td>

        </tr>

        <tr>

            <td><button>4</button></td>

            <td><button>5</button></td>

            <td><button>6</button></td>

            <td><button>+</button></td>

            <td><button>-</button></td>

        </tr>

        <tr>

            <td><button>1</button></td>

            <td><button>2</button></td>

            <td><button>3</button></td>

            <td><button>*</button></td>

            <td><button>/</button></td>

        </tr>

        <tr>

            <td><button>0</button></td>

            <td><button>.</button></td>

            <td><button>%</button></td>

            <td colspan="2"><button class="setChange" id="gainResult">Enter</button></td>

        </tr>

    </table>

    <script type="text/javascript" src='index.js'>       

    </script>

 CSS代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

*{margin: 0px; padding: 0px;}

        .errorHint{position: absolute; left: 130px; top:-282px;}

        .showError{border:1px solid red;}

        table{ border: 2px solid #996c33; width: 550px; padding: 10px; margin: 150px auto) left center no-repeat; border-radius: 10px;}

        table td{

            text-align: center;

            width: 100px;

            height: 40px;

            padding-left: 2px;

            padding-bottom: 2px;

        }

        table th{

            font-size: 18px;

            font-family:'楷体';

            color#8B0000;

        }

        table td button{

            width: 98%;

            height: 98%;

            font-size: 16px;

            font-family: 'Microsoft yahei';

            background: none;

            color#8B4726;

            outline:none;

            border:1px solid #000;

            border-radius: 5px;

            cursor: pointer;

        }

        table td input{

            width: 100%;

            margin: 10px 0;

            padding: 5px;

            border:1px solid #996c33;

            box-sizing: border-box;                    

            text-align: right;

            font-size: 16px;

            font-family: 'Microsoft yahei';

        }

JS代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

var oinput=document.getElementsByTagName('input')[0];

        //获取外部样式

        function getStyle(obj, name)

        {

            if(obj.currentStyle)

            {

                return obj.currentStyle[name];

            }

            else

            {

                return getComputedStyle(obj, false)[name];

            }

        }

        //渐变动画

        function move(obj,attr,tar){

            clearInterval(obj.timer);

            obj.timer=setInterval(function(){

                var cur=parseInt(getStyle(obj,attr));

                var itarget=parseInt(tar);

                var speed=(itarget-cur)/6;

                speed=speed>0?Math.ceil(speed):Math.floor(speed);

                obj.style[attr]=parseInt(getStyle(obj,attr))+speed+'px';

                if(speed==0){

                    clearInterval(obj.timer);

                }

            },30);

        }

        //事件绑定函数

        function addEvent(obj,ev,fun){

            if(obj.attachEvent){

                obj.attachEvent('on'+ev,fun);

            }else{

                obj.addEventListener(ev,fun,false);

            }

        }

        //阻止默认行为

        function stopEvent(ev){

            var e=ev||window.event;

            if(e.preventDefault){

                e.preventDefault();

            }

            else{

                e.returnValue=false;//ie

            }

        }

        //计算最终结果

        function getResult(){

            function evalResult(){

                var result=eval(oinput.value);

                return result;         

            }

            //捕获异常

            try{

                var x=evalResult();

                return x;

            }

            catch (e){

                oinput.className='showError';

                var errorHint=document.getElementById('errorHint');

                move(errorHint,'top',0);

                setTimeout(function(){

                    oinput.className='';

                    move(errorHint,'top',-282);

                },2000);

                return oinput.value;

            }

        }

        //文本框获取焦点,错误提示消失

        //按下回车得到结果

        function enterResult(ev){

            var e=ev||window.event;

            if(e.keyCode==13){

                stopEvent(ev);//阻止enter键的默认行为

                var result=getResult();

                oinput.value=result;

            }

        }

        //绑定点击事件

        function init(){

            var otable=document.getElementsByTagName('table')[0];

            addEvent(otable,'keydown',function(ev){

                enterResult(ev);

            });

            addEvent(otable,'click',function(ev){

                stopEvent(ev);

                var e=ev||window.event;

                var itat=e.target||e.srcElement;

                var obtns=document.getElementsByTagName('button');

                if(itat.nodeName.toLowerCase()=='button'){

                    for(var i=0;i<obtns.length;i++){

                        obtns[i].style.borderColor='#000';

                    }

                    itat.style.borderColor='white';

                    if(itat.className!='setChange'){

                        if(oinput.value=='0'){

                            oinput.value='';

                            oinput.value+=itat.innerHTML;

                        }

                        else{

                            oinput.value+=itat.innerHTML;

                        }

                    }else{

                        if(itat.id=='backSpace'){

                            oinput.value=oinput.value.toString().slice(0,-1);

                        }

                        else if(itat.id=='clearNum'){

                            oinput.value='0';

                        }else{

                            var result=getResult();

                            oinput.value=result;

                        }

                    }

                }

            });

        }

        init();

思路:

1.使用table画出整个界面。

借鉴了其他人已经实现了的结构,发现他们有一些人没有直接在td里写1,2,3或者退格什么的,而是又嵌套了一个button,我其实到现在也没有太理解为什么要这样,只是在排版的时候感觉到有些作用:因为margin对td 不起作用,只能设置padding。

2.使用eval函数计算最终结果,并捕获异常

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

function getResult(){

   function evalResult(){

    var result=eval(oinput.value);

    return result;  

   }

   //捕获异常

   try{

    var x=evalResult();

    return x;

   }

   catch (e){

    oinput.className='showError';

    var errorHint=document.getElementById('errorHint');

    move(errorHint,'top',0);

    setTimeout(function(){

     oinput.className='';

     move(errorHint,'top',-282);

    },2000);

    return oinput.value;

   }

  }

eval函数第一次使用,w3c上对它的定义如下

eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码。

有了这个函数得到最终结果就很容易了。我的思路是在用户输入要计算的式子时不加干预,最终的计算从input输入框中获取value值,然后把这个value值作为参数传递给eval,并使用try catch(exception)来捕获并处理异常。

3.通过事件代理绑定事件

因为每个button都需要有一个点击事件,如果一个一个去绑定,会导致代码十分的不简洁,而且效率也非常低。这时就可以考虑使用事件代理,由于事件冒泡的原理,我们可以把点击事件绑定在table上,然后通过判断事件发生的具体对象来做出不同的反应,调用不同的函数。

4.其他效果

可以根据自己的设计思路,添加其他的效果。我主要是添加了一个错误提示的动画:如果eval函数抛出异常,则从上面缓慢滑下一个图片,并且通过setTimeout来设置了停留的时间。

5.注意细节

在设置enter键按下获得结果的时候,keydown事件对象应该为整个table,并且应该阻止enter键的默认行为
获取元素样式时需要写一个兼容函数,因为obj.style.attr只能获取行间样式,要像获取外部样式需要用getComputedStyle(obj,false)[attr]或兼容IE的obj.currentStyle[attr]。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值