为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

胡子哥哥 2022-11-11 16:33:38
我只是想在单击时更改特定按钮的背景。我通过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>
查看完整描述

3 回答

?
长风秋雁

TA贡献1757条经验 获得超7个赞

我已经修改了你的代码,修复了一些问题。我假设您有一个带有 id的元素,它与可以通过 访问的元素body不同。bodydocument.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";

}


查看完整回答
反对 回复 2022-11-11
?
小唯快跑啊

TA贡献1863条经验 获得超2个赞

您的代码存在多个问题。

你应该得到body带有 的元素getElementsByTagName,它返回数组。所以选择第一个元素。

设置 onclick 属性应该使用inot text的值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

}


查看完整回答
反对 回复 2022-11-11
?
斯蒂芬大帝

TA贡献1827条经验 获得超8个赞

您可以通过引用其自身的属性来定位单击的元素,而不是分配和尝试使用 ID 属性event。如果您要分析event(使用控制台),您会注意到几个属性 -target允许访问元素本身,这有助于简化showOptions功能。在这种情况下,您也可以简单地使用this从内部引用按钮本身showOptions- 这将使其更加简单 - 例如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 );

})


向元素添加任意属性不是最佳实践 - 而不是分配x,y您应该改用dataset属性 - 所以data-x是data-y正确的。


查看完整回答
反对 回复 2022-11-11
  • 3 回答
  • 0 关注
  • 144 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信