无法在具有函数的数组中定位 JS 生成的按钮,出现"Cannot read property 'setAttribute' of null"错误



我只是想在单击某个特定按钮时更改它的背景。我通过for循环生成了100个按钮(希望以后能制作一个简单的游戏(作为数组,同时分配了一个id和一个不同的函数调用(基于循环的递增"I"值(,但实际上无法在点击时改变背景,而是出现了以下错误"未捕获的TypeError:无法读取null的属性"setAttribute"在showOptions(brain.js:31(在HTMLButtonElement.onclick(index.html:15(";

我的代码如下

var btn = [];
function generateBoard() {
for (i = 0; i < 100; i++) {
var modulo = i % 10;
var up, forLeft;
btn[i] = document.createElement("BUTTON");
var element = document.getElementById("body");
//btn[i].innerText = "CLICK ME";
element.appendChild(btn[i]);
btn[i].style.backgroundColor = "white";
btn[i].id = i;
btn[i].style.width = "50px";
btn[i].style.height = "40px";
btn[i].style.position = "absolute";
btn[i].style.top = modulo * 100;
btn[i].style.left = Math.floor(i / 10) * 100;
btn[i].x = (i + 10) % 10;
btn[i].y = Math.floor(i / 10);
document
.getElementById(btn[i].id)
.setAttribute("onclick", "showOptions(i)");
btn[i].innerText = btn[i].id;
console.log(
btn[i].id +
" " +
btn[i].style.left +
" " +
btn[i].style.top +
" " +
btn[i].x +
" " +
btn[i].y
);
}
}
generateBoard();
function showOptions(i) {
document.getElementById(i).setAttribute("style", "background-color: red;"); //this is line 31
}

在console.log中,我实际上得到了正确的数字btn[I].id,这很奇怪。

错误的(index.html:15(行只是

</html>

您的代码存在多个问题
您应该使用返回数组的getElementsByTagName来获取body元素。所以选择第一个元素
设置onclick属性应使用i的值,而不是文本i

var btn = [];
function generateBoard() {
for (i = 0; i < 100; i++) {
var modulo = i % 10;
var up, forLeft;
btn[i] = document.createElement("BUTTON");
var element = document.getElementsByTagName("body")[0];
//btn[i].innerText = "CLICK ME"; 
element.appendChild(btn[i]);
btn[i].style.backgroundColor = "white";
btn[i].id = i;
btn[i].style.width = "50px";
btn[i].style.height = "40px";
btn[i].style.position = "absolute";
btn[i].style.top = modulo * 100;
btn[i].style.left = Math.floor(i / 10) * 100;
btn[i].x = (i + 10) % 10;
btn[i].y = Math.floor(i / 10);

document.getElementById(btn[i].id).setAttribute('onclick', 'showOptions(' + i + ')');
btn[i].innerText = btn[i].id;

console.log(btn[i].id + " " + btn[i].style.left + " " + btn[i].style.top + " " + btn[i].x + " " + btn[i].y);
}
}
generateBoard();
function showOptions(i) {
document.getElementById(i).setAttribute("style", "background-color: red;"); //this is line 31
}

我重新编写了您的代码,修复了一些问题。我假设您有一个id为body的元素,它与可以通过document.body访问的body元素不同。

var buttons = [];
function generateBoard(){
for(i = 0; i < 100; i++) {
var modulo = i % 10;
buttons[i] = document.createElement("BUTTON");
document.getElementById("body").appendChild(buttons[i]);
//buttons[i].innerText = "CLICK ME";
buttons[i].style.backgroundColor = "white";
buttons[i].id = i;
buttons[i].style.width = "50px";
buttons[i].style.height = "40px";
buttons[i].style.position = "absolute";
buttons[i].style.top = modulo * 100;
buttons[i].style.left = Math.floor(i / 10) * 100;
buttons[i].x = (i + 10) % 10;
buttons[i].y = Math.floor(i / 10);
buttons[i].addEventListener('click', function(event) {
// This code is run when the button is clicked
// Note I am passing the element, rather than an id
showOptions(this);
});
buttons[i].innerText = i;
console.log(buttons[i].id + " " + buttons[i].style.left + " " + buttons[i].style.top + " " + buttons[i].x + " " + buttons[i].y);
}
}
generateBoard();
function showOptions(button){
button.style.backgroundColor = "red";
}

您可以通过引用event本身的属性来定位单击的元素,而不是分配并尝试使用ID属性。如果您要分析event(使用控制台(,您会注意到几个属性-target允许访问元素本身,这有助于简化showOptions函数。在这种情况下,您也可以简单地使用thisshowOptions中引用按钮本身,这将使其更加简单,例如this.style.backgroundColor='red';

let bttns=[];
const generateBoard=function( s=100 ){
const showOptions=function(e){
e.target.style.backgroundColor='red';
};
for( let i=0; i < s; i++ ){
/* create a new button and add properties */
let bttn=document.createElement('button');
bttn.setAttribute('id',i);
bttn.setAttribute('data-x',((i+10)%10));
bttn.setAttribute('data-y',Math.floor(i/10));
bttn.style.left=( Math.floor( i / 10 ) * 100 )+'px';
bttn.style.top=( ( i % 10 ) * 100 )+'px';
bttn.style.width = '50px';
bttn.style.height = '40px';
bttn.style.position = 'absolute';
bttn.innerText=i;
/* bind event listener */
bttn.addEventListener('click', showOptions );
/* add to the DOM */
document.body.appendChild( bttn );
/* if it is important to have in an array... */
bttns.push( bttn );
}
}
document.addEventListener('DOMContentLoaded',(e)=>{
generateBoard( 100 );
})

向元素添加任意属性不是最佳做法-与其指定xy,不如使用dataset属性-因此data-xdata-y是正确的。

相关内容

最新更新