Cette fois, je vais vous apporter une explication détaillée des étapes pour implémenter une calculatrice simple avec JS. Quelles sont les précautions pour implémenter une calculatrice simple avec JS Voici un cas pratique, prenons un. regarder.
J'ai toujours voulu écrire une calculatrice lors de ma révision finale. Pendant mon temps libre, je réfléchissais aussi à la façon de la mettre en œuvre. Je pensais que cela ne devrait pas être difficile, mais je voulais juste l'écrire. . Hier, nous avons finalement commencé la construction. Au début, je pensais que cela prendrait environ une semaine ou au moins deux jours. Je pensais que je pourrais rentrer chez moi pendant deux jours après l'achèvement. Mais je ne m'attendais pas à ce que l'ensemble du processus de mise en œuvre soit relativement fluide. Il a fallu environ six heures hier pour terminer la conception et la mise en œuvre.
Je n'ai pas écrit beaucoup de code depuis environ un mois. Tout mon cerveau n'y est pas habitué, ma réponse est lente et certaines choses de base sont un peu floues. Il se peut que je ne l'ai pas bien compris au départ et qu'il n'y avait aucune autre pratique, ce qui a entraîné une efficacité quelque peu faible.
Texte
code html :
<p class="errorHint" id="errorHint"><img src="https://github.com/crystalYY/calculator/blob/master/img/error.png?raw=true"></p> <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>
CSScode :
*{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; background:url(https://github.com/crystalYY/calculator/blob/master/img/bg2.jpg?raw=trueg) 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'; }
Code JS :
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();
Interface d'affichage normale
Interface d'invite d'erreur
Implémentation de l'effet : http://codepen.io/cristalYY/pen/jAkNVz
Idées de mise en œuvre
1. Utilisez un tableau pour dessiner l'intégralité de l'interface.
J'ai appris des structures que d'autres personnes ont implémentées et j'ai découvert que certaines d'entre elles n'écrivaient pas 1, 2, 3 ou retour arrière directement dans td, mais imbriquaient plutôt un bouton. Je ne comprends pas très bien pourquoi cela est fait. J'ai juste l'impression que cela a un certain effet lors de la composition : comme la marge n'a aucun effet sur td, le remplissage ne peut être défini.
2. Utilisez la fonction eval pour calculer le résultat final et intercepter l'exception
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; } }
La première fois que la fonction eval est utilisée, elle est définie comme suit sur w3c
La fonctioneval() peut calculer une chaîne et y exécuter le code JavaScript.
Obtenir le résultat final est facile avec cette fonction. Mon idée est de ne pas intervenir lorsque l'utilisateur entre la formule à calculer. Le calcul final obtient la valeur de la zone de saisie, puis transmet la valeur en tant que paramètre à évaluer et utilise try catch (exception) pour capturer et gérer les exceptions. .
3. Lier les événements via des agents d'événements
Parce que chaque bouton nécessite un événement de clic, si vous les liez un par un, le code sera très incohérent. très inefficace. À ce stade, vous pouvez envisager d'utiliser un proxy d'événement. En raison du principe de bouillonnement d'événements, nous pouvons lier l'événement de clic à la table, puis effectuer différentes réactions et appeler différentes fonctions en jugeant l'objet spécifique où l'événement s'est produit.
4. Autres effets
Vous pouvez ajouter d'autres effets selon vos propres idées de conception. J'ai principalement ajouté une animation d'invite d'erreur : si la fonction eval lève une exception , faites glisser lentement une image d'en haut et définissez le temps de séjour via setTimeout.
5. Faites attention aux détails
Lorsque vous appuyez sur la touche Entrée pour obtenir le résultat, l'objet d'événement keydown doit être la table entière et le comportement par défaut de la touche Entrée doit être empêchée
Lors de l'obtention du style d'élément, vous devez écrire une fonction de compatibilité, car obj.style.attr ne peut obtenir que le style interligne. Pour obtenir le style externe, vous devez utiliser getComputedStyle(obj, false)[attr] ou obj.currentStyle[attr ] compatible IE.
Je pense que vous maîtrisez la méthode après avoir lu le cas dans cet article. Pour des informations plus intéressantes, veuillez prêter attention aux autres articles connexes sur le site Web chinois de php !
Lecture recommandée :
Un résumé des méthodes de saut de routage dans différentes versions de React
Une explication détaillée des étapes utiliser Angular route guard
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!