无法使用函数在数组中定位 JS 生成的按钮,出现“无法读取属性

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


我的代码如下


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>



胡子哥哥
浏览 145回答 3
3回答

长风秋雁

我已经修改了你的代码,修复了一些问题。我假设您有一个带有 id的元素,它与可以通过 访问的元素body不同。bodydocument.bodyvar buttons = [];function generateBoard(){&nbsp; &nbsp; for(i = 0; i < 100; i++) {&nbsp; &nbsp; &nbsp; &nbsp; var modulo = i % 10;&nbsp; &nbsp; &nbsp; &nbsp; buttons[i] = document.createElement("BUTTON");&nbsp; &nbsp; &nbsp; &nbsp; document.getElementById("body").appendChild(buttons[i]);&nbsp; &nbsp; &nbsp; &nbsp; //buttons[i].innerText = "CLICK ME";&nbsp; &nbsp; &nbsp; &nbsp; buttons[i].style.backgroundColor = "white";&nbsp; &nbsp; &nbsp; &nbsp; buttons[i].id = i;&nbsp; &nbsp; &nbsp; &nbsp; buttons[i].style.width = "50px";&nbsp; &nbsp; &nbsp; &nbsp; buttons[i].style.height = "40px";&nbsp; &nbsp; &nbsp; &nbsp; buttons[i].style.position = "absolute";&nbsp; &nbsp; &nbsp; &nbsp; buttons[i].style.top = modulo * 100;&nbsp; &nbsp; &nbsp; &nbsp; buttons[i].style.left = Math.floor(i / 10) * 100;&nbsp; &nbsp; &nbsp; &nbsp; buttons[i].x = (i + 10) % 10;&nbsp; &nbsp; &nbsp; &nbsp; buttons[i].y = Math.floor(i / 10);&nbsp; &nbsp; &nbsp; &nbsp; buttons[i].addEventListener('click', function(event) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // This code is run when the button is clicked&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Note I am passing the element, rather than an id&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; showOptions(this);&nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; &nbsp; buttons[i].innerText = i;&nbsp; &nbsp; &nbsp; &nbsp; console.log(buttons[i].id + " " + buttons[i].style.left + " " + buttons[i].style.top + " " + buttons[i].x + " " + buttons[i].y);&nbsp; &nbsp; }}generateBoard();function showOptions(button){&nbsp; &nbsp; button.style.backgroundColor = "red";}

小唯快跑啊

您的代码存在多个问题。你应该得到body带有 的元素getElementsByTagName,它返回数组。所以选择第一个元素。设置 onclick 属性应该使用inot text的值i。var btn = [];function generateBoard() {&nbsp; for (i = 0; i < 100; i++) {&nbsp; &nbsp; var modulo = i % 10;&nbsp; &nbsp; var up, forLeft;&nbsp; &nbsp; btn[i] = document.createElement("BUTTON");&nbsp; &nbsp; var element = document.getElementsByTagName("body")[0];&nbsp; &nbsp; //btn[i].innerText = "CLICK ME";&nbsp;&nbsp; &nbsp; element.appendChild(btn[i]);&nbsp; &nbsp; btn[i].style.backgroundColor = "white";&nbsp; &nbsp; btn[i].id = i;&nbsp; &nbsp; btn[i].style.width = "50px";&nbsp; &nbsp; btn[i].style.height = "40px";&nbsp; &nbsp; btn[i].style.position = "absolute";&nbsp; &nbsp; btn[i].style.top = modulo * 100;&nbsp; &nbsp; btn[i].style.left = Math.floor(i / 10) * 100;&nbsp; &nbsp; btn[i].x = (i + 10) % 10;&nbsp; &nbsp; btn[i].y = Math.floor(i / 10);&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; document.getElementById(btn[i].id).setAttribute('onclick', 'showOptions(' + i + ')');&nbsp; &nbsp; btn[i].innerText = btn[i].id;&nbsp; &nbsp; console.log(btn[i].id + " " + btn[i].style.left + " " + btn[i].style.top + " " + btn[i].x + " " + btn[i].y);&nbsp; }}generateBoard();function showOptions(i) {&nbsp; document.getElementById(i).setAttribute("style", "background-color: red;"); //this is line 31}

斯蒂芬大帝

您可以通过引用其自身的属性来定位单击的元素,而不是分配和尝试使用 ID 属性event。如果您要分析event(使用控制台),您会注意到几个属性 -target允许访问元素本身,这有助于简化showOptions功能。在这种情况下,您也可以简单地使用this从内部引用按钮本身showOptions- 这将使其更加简单 - 例如this.style.backgroundColor='red';let bttns=[];const generateBoard=function( s=100 ){&nbsp; const showOptions=function(e){&nbsp; &nbsp; e.target.style.backgroundColor='red';&nbsp; };&nbsp; for( let i=0; i < s; i++ ){&nbsp; &nbsp; /* create a new button and add properties */&nbsp; &nbsp; let bttn=document.createElement('button');&nbsp; &nbsp; &nbsp; bttn.setAttribute('id',i);&nbsp; &nbsp; &nbsp; bttn.setAttribute('data-x',((i+10)%10));&nbsp; &nbsp; &nbsp; bttn.setAttribute('data-y',Math.floor(i/10));&nbsp; &nbsp; &nbsp; bttn.style.left=( Math.floor( i / 10 ) * 100 )+'px';&nbsp; &nbsp; &nbsp; bttn.style.top=( ( i % 10 ) * 100 )+'px';&nbsp; &nbsp; &nbsp; bttn.style.width = '50px';&nbsp; &nbsp; &nbsp; bttn.style.height = '40px';&nbsp; &nbsp; &nbsp; bttn.style.position = 'absolute';&nbsp; &nbsp; &nbsp; bttn.innerText=i;&nbsp; &nbsp; &nbsp; /* bind event listener */&nbsp; &nbsp; &nbsp; bttn.addEventListener('click', showOptions );&nbsp; &nbsp; /* add to the DOM */&nbsp; &nbsp; document.body.appendChild( bttn );&nbsp; &nbsp; /* if it is important to have in an array... */&nbsp; &nbsp; bttns.push( bttn );&nbsp; }}document.addEventListener('DOMContentLoaded',(e)=>{&nbsp; generateBoard( 100 );})向元素添加任意属性不是最佳实践 - 而不是分配x,y您应该改用dataset属性 - 所以data-x是data-y正确的。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript