使用键值对数组遍历多个按钮,以添加带循环的事件侦听器



我正在做一个简单的计算器项目

我正在尝试自动将事件侦听器添加到各种数字按钮 (1-9)。

事件侦听器将侦听按钮上的单击事件,这些事件会导致 HTML 的显示部分发生变化(类 = .display)

键值对是包含各种相应值的 B1-B9。

我想出了下面的每个循环。由于某种原因,它会导致所有数字按钮应用数字 9;我相信这是每个循环的原因。

我不确定如何完全解决它。我还提出了一个导致另一个问题的替代 FOR 循环。pairs[Properties[i]].toString() 返回未定义。

有趣的是,如果我交换对[属性[i]].toString() 只到 i 那么就会出现相同的问题

帮助真的很感激,谢谢你。

const pairs = {
b1: 1,
b2: 2,
b3: 3,
b4: 4,
b5: 5,
b6: 6,
b7: 7,
b8: 8,
b9: 9,
};
var Properties = Object.keys(pairs);
function loadButtons () {
for (var item in pairs) {
//for each key property in pairs
console.log(item);
let targetCell = document.querySelector("." + item.toString())
// querySelector only targets the FIRST element found
// in this case only 1 for that name
console.log(targetCell);
targetCell.addEventListener('click', () => {
// you want it to manipulate the display as and when clicked
var currentDisplay = document.querySelector(".display").innerHTML.toString();
newDisplay = currentDisplay + pairs[item].toString();
document.querySelector(".display").innerHTML = newDisplay;
})

// console.log(pairs[item]);
// // pairs[item] retrieves the value to that "key"        
}
};
function alternative() {
var i;
var Properties = Object.keys(pairs);
for (i = 0; i < Properties.length; i++) {
let targetCell = document.querySelector("." + Properties[i].toString())
// querySelector only targets the FIRST element found
// in this case only 1 for that name
console.log(targetCell);
targetCell.addEventListener('click', () => {
// you want it to manipulate the display as and when clicked
var currentDisplay = document.querySelector(".display").innerHTML.toString();
newDisplay = currentDisplay + pairs[Properties[i]].toString();
document.querySelector(".display").innerHTML = newDisplay;
})
};
};

预期应该是单击 1 将字符串"1"添加到计算器的当前字符串中,依此类推。

function onClick(item, pairs) {
return () => {
// you want it to manipulate the display as and when clicked
var currentDisplay = document.querySelector(".display").innerHTML.toString();
var newDisplay = currentDisplay + pairs[item].toString();
document.querySelector(".display").innerHTML = newDisplay;
}
} 
var Properties = Object.keys(pairs);
function loadButtons () {
for (var item in pairs) {
//for each key property in pairs
console.log(item);
let targetCell = document.querySelector("." + item.toString())
// querySelector only targets the FIRST element found
// in this case only 1 for that name
console.log(targetCell);
targetCell.addEventListener('click', onClick(item, pairs)) 

// console.log(pairs[item]);
// // pairs[item] retrieves the value to that "key"        
}
};

您应该使用事件委派,而不是循环并将事件附加到每个按钮。下面是一个示例:

var keyboard = document.getElementById('keyboard');
var display = document.getElementById('display');
keyboard.addEventListener('click', function(ev) {
var val = ev.target.id;
if (ev.target.localName === 'button') {
display.innerText += val;
}
});
.calculator {
width: 300px;

background: whitesmoke;
}
#display {
height: 50px;
background: #d2d2d2;
border: 1px solid #9c9c9c;
margin: 10px auto 10px;
font-size: 20px;
line-height: 50px;
padding: 0 10px;
}
#keyboard {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
}
button {
font-size: 20px;

padding: 20px;
margin: 5px;

cursor: pointer;
}
<div class="calculator">
<div id="display" contenteditable="true" >

</div>
<div id="keyboard">
<button id="0">0</button>
<button id="1">1</button>
<button id="2">2</button>
<button id="3">3</button>
<button id="4">4</button>
<button id="5">5</button>
<button id="6">6</button>
<button id="7">7</button>
<button id="8">8</button>
<button id="9">9</button>
</div>
</div>

我会这样做,但这不是我猜的唯一方法,可能有更好的方法。

const BUTTONS_NAMESVALUES={
//-- sound awful when a loop can do that!
bt0:0,bt1:1,bt2:2,bt3:3,bt4:4,bt5:5,bt6:6,bt7:7,bt8:8,bt9:9
}
function checkButtonValue(bt){
if(BUTTONS_NAMESVALUES[bt.id] !=null && BUTTONS_NAMESVALUES[bt.id] !='undefined'){
return bt.innerHTML;
}return;
}
//a button may look like that
<button id="bt1">1</button>
//-- with listener:
document.getElementById('bt1').addEventListener('click', function(e){
let chk=checkButtonValue(this);
if(chk!=null && chk!='undefined' && chk!=''){
document.getElementById('calculatorScreen').innerHTML=''+document.getElementById('calculatorScreen').innerHTML+chk;
}
});

我希望这有所帮助。我只是替换了类名".display",它很容易成为错误的来源(因为它是 CSS 属性的名称,在这种情况下,使用 id 在 HTML+ 中显示任何东西都会更好,因为它是一个独特的元素,不会弄错,类不是)并且不是很准确(因为我写了一个正确的常量名称,它有一些含义,而不是对,他们实际上没有任何意义^^)。

我也没有将代码自动化到循环中,但这是脚本中最简单的部分。

最新更新