以下是代码:
var listener = document.querySelectorAll('#calculator span');
// look at each widget pressed and update calculator
for (var count = 0; count < listener.length; count++) {
listener[count].onclick = function() {
update()
};
}
function update() {
// Get input of calculator screen and button pressed
var widget = this.innerHTML;
var screen = document.querySelector('.screen');
var screenIn = screen.innerHTML;
// clear the screen
if (widget == 'DEL') {
screen.innerHTML = '';
}
// if = sign is pressed, evaluate the screen input
// TODO: handle special cases (like if the input equation isn't syntactically correct)
else if (widget == '=') {
screen.innerHTML = eval(inputEq);
}
// change x to * for evaluator
else if (widget == 'x') {
screen.innerHTML += '*';
}
//clear the text inside the screen
else if (widget == 'C') {
screen.innerHTML = "";
} else {
screen.innerHTML += widget;
}
}
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="main.js"></script>
<link href="css.css" type="text/css" rel="stylesheet" />
</head>
<body>
<div id="calculator">
<!-- Screen and clear button -->
<div class="top">
<span class="clear">C</span>
<div class="screen"></div>
</div>
<div class="buttons">
<!-- number operators and other buttons -->
<span>7</span>
<span>8</span>
<span>9</span>
<span class="operator">DEL</span>
<span>4</span>
<span>5</span>
<span>6</span>
<span class="operator">/</span>
<span>1</span>
<span>2</span>
<span>3</span>
<span class="operator">x</span>
<span>+/-</span>
<span>0</span>
<span>.</span>
<span class="operator">-</span>
<span>(</span>
<span>)</span>
<span class="eval">=</span>
<span class="operator">+</span>
</div>
</div>
</body>
</html>
由于某些原因,单击时屏幕部分上没有显示任何跨度值。我不确定发生了什么。我尝试了各种技术来将更新功能分配给按钮单击,但似乎没有任何效果。如果你们注意到我不知道的事情,请告诉我。
这是CSS
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font: bold 14px Verdana, Geneva, sans-serif;
}
html {
height: 100%;
background: black;
background-size: cover;
}
#calculator {
width: 325px;
height: auto;
margin: 100px auto;
padding: 20px 20px 9px;
background: #b6ffad;
border-radius: 20px;
box-shadow: 0px 4px #94ce8c, 0px 10px 15px rgba(0, 0, 0, 0.2);
}
.top span.clear {
float: left;
}
.top .screen {
height: 40px;
width: 212px;
float: right;
padding: 0 10px;
background: rgba(0, 0, 0, 0.2);
border-radius: 20px;
box-shadow: inset 0px 4px rgba(0, 0, 0, 0.2);
font-size: 17px;
line-height: 40px;
color: white;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
text-align: right;
letter-spacing: 1px;
}
.buttons, .top {overflow: hidden;}
.buttons span, .top span.clear {
float: left;
position: relative;
top: 0;
cursor: pointer;
width: 66px;
height: 36px;
background: white;
border-radius: 20px;
box-shadow: 0px 4px rgba(0, 0, 0, 0.2);
margin: 0 7px 11px 0;
color: #565656;
line-height: 36px;
text-align: center;
user-select: none;
transition: all 0.2s ease;
}
.buttons span.operator {
background: #afafaf;
box-shadow: 0px 4px #878787;
margin-right: 0;
color: white;
}
.buttons span.eval {
background: #4c4c4c;
box-shadow: 0px 4px #333333;
color: white;
}
.top span.clear {
background: #ff9fa8;
box-shadow: 0px 4px #ff7c87;
color: white;
}
.buttons span:hover {
background: #82d179;
box-shadow: 0px 4px #64a05d;
color: white;
}
.buttons span.eval:hover {
background: #e2e2e2;
box-shadow: 0px 4px #bababa;
color: black;
}
.top span.clear:hover {
background: #f68991;
box-shadow: 0px 4px #d3545d;
color: white;
}
.buttons span:active {
box-shadow: 0px 0px #ffffff;
top: 4px;
}
.buttons span.eval:active {
box-shadow: 0px 0px #ffffff;
top: 4px;
}
.top span.clear:active {
top: 4px;
box-shadow: 0px 0px #ffffff;
}
答案 0 :(得分:2)
以这种方式分配onclick处理程序不会自动传递被单击的元素作为处理程序的上下文。因此,update
中对此内容的引用是指window
而不是<span>
元素。
要实现您的目标,请按以下步骤修改.js文件:
for (var count = 0; count < listener.length; count++) {
listener[count].onclick = function(event){
// ^---include the event param here
update(event);
// ^---- pass the reference to your update function
};
}
// v-----define an event parameter 'e' in your update function
function update(e) {
// Your new widget variable will be:
var widget = e.target.innerHTML;
//...include the rest of your code as is
// apart from:
else if (widget == '=') {
//screen.innerHTML = eval(inputEq);
// ^---- inputEq not defined anywhere
// change to:
screen.innerHTML = eval(screen.innerHTML);
}
}
答案 1 :(得分:1)
您在加载文档之前查询元素。在</body>
标记之前移动脚本(在您要查询的元素下面),因此它将在元素存在之后加载,或者将您的查询(和onclick处理程序定义)放在onload
事件处理程序中。
第二件事是更新功能,以及你绑定它的方式。
我知道您希望更新函数中的this
是按钮元素,其中innerHTML将是其编号或运算符。但是当你像你一样绑定更新函数时:
listener[count].onclick = function(){update()};
然后this
将成为匿名函数(){}内的按钮,如:
listener[count].onclick = function(){
this.innerHTML; // This would be a number/operator of a button.
update(); // Function will be called but button wont be its "this" variable, but the window.
};
您可以传递此更新作为参数或直接绑定更新,如:
listener[count].onclick = update;
请注意,没有()
(调用运算符),只是通过函数传递变量,而不是结果。
修改强>
为了进一步解释,你可以移动这一行:
<script type="text/javascript" src="main.js"></script>
到
<span class="operator">+</span>
</div>
</div>
<script type="text/javascript" src="main.js"></script> <!-- here -->
</body>
因此,脚本在它所依赖的元素已经加载和已知之后被触发,或者,您可以在页面加载后开始查询按钮,所以这部分:
var listener = document.querySelectorAll('#calculator span');
// look at each widget pressed and update calculator
for (var count = 0; count < listener.length; count++) {
listener[count].onclick = function() {
update()
};
}
看起来像这样:
onload = function(){
var listener = document.querySelectorAll('#calculator span');
// look at each widget pressed and update calculator
for (var count = 0; count < listener.length; count++) {
listener[count].onclick = function() {
update()
};
}
}
现在是window.onload事件处理程序。
使用绑定更新功能按钮,我的意思是,而不是:
for (var count = 0; count < listener.length; count++) {
listener[count].onclick = function() {
update()
};
}
做的:
for (var count = 0; count < listener.length; count++) {
listener[count].onclick = update;
}
现在在更新功能中,this
将是按钮,而不是窗口。