新的子元素包含父元素。

4
我正在尝试制作一个井字游戏,但是当我将背景图像更改为X或O的图像时出现问题。我正在使用事件监听器单击<td>单元格以获取其id。

这是创建带有所有单元格标识和包含不同id的所有单元格中包含图像的表格的函数:

function BuildTable(rows, cols) {
    BuildDivJeu();
    var table = document.createElement("TABLE");
    table.id = "Table";
    document.getElementById("Jeu").appendChild(table);
    for (var row = 1; row <= rows; row++) {
        var rangee = document.createElement("TR");
        rangee.id = row;
        document.getElementById("Table").appendChild(rangee);
        for (var col = 1; col <= cols; col++) {
            var cellule = document.createElement("TD");
            var img = document.createElement("IMG");
            cellule.id = "R" + row + "C" + col;
            img.setAttribute("id", cellule.id);
            img.setAttribute("src", "Images/VN.png");
            img.setAttribute("alt", "VN")

            cellule.appendChild(img);
            document.getElementById(row).appendChild(cellule);
            cellule.addEventListener("click", Jouer);
        }
    }
}

这是我的函数,根据点击的单元格更改单元格中的图像。
 function Jouer() {
     var x = event.currentTarget
     var id = x.id;
     var imgx = document.getElementById(id);
     var imgo = document.getElementById(id);
     if (turn % 2 == 0) {
         if (x.alt != "VN" | x.alt != "ON") {
             if (imgx.hasAttribute("alt")) {
                 imgx.setAttribute("src", "Images/XN.png");
                 imgx.setAttribute("id", "XN");
                 imgx.setAttribute("alt", "XN");
             }
             x.appendChild(imgx);
         }
         turn++;
     } else {
         if (x.id != "VN" | x.id != "XN") {
             if (imgo.hasAttribute("alt")) {
                 imgo.setAttribute("src", "Images/ON.png");
                 imgo.setAttribute("id", "ON");
                 imgo.setAttribute("alt", "ON");
             }
             x.appendChild(imgo);
         }
         turn++;
     }
 }

当我点击想要放置X或O的单元格时,它不能工作,并显示了此帖子标题中的错误消息。我想知道如何继续更改单元格中的图像及其新ID。
1个回答

6
你在 Jouer() 中的逻辑有误。我不知道你点击单元格时到底想做什么,但这是你实际上正在做的事情和为什么会出现错误。
问题的一部分是你给<td><img>都赋予了完全相同的id。这是不可以的,id值必须在文档中是唯一的。当你调用document.getElementById(id)时,它很可能只返回匹配该id的第一个对象(虽然由于这是非法的HTML语法,确切的行为未被规范定义)。
此外,以下是Jouer()的第一部分正在做的事情:
 // get the element that was clicked on which is the <td> element
 var x = event.currentTarget
 // get the id of the element that was clicked on
 var id = x.id;
 // find the element that has that id, which is probably going to be the containing <td> 
 // since it's the first item with that id
 var imgx = document.getElementById(id);
 // assign same element to imgo
 var imgo = document.getElementById(id);

 // so, at this point x and imgx and imgo all point at the containing <td>

然后,在该函数的后面,您尝试执行以下操作:
 x.appendChild(imgx);

但是,ximgx是相同的元素。你不能将一个元素附加到它本身。错误信息本身略微令人困惑,因为它说“新的子元素包含父元素”,但他们在代码中可能正在检查的是新的父级是否在子层次结构中的任何位置,这将使此操作非法,并且它位于层次结构的顶部,因此您会收到此错误消息。
如果您愿意用言语解释单击时要发生的确切事件,那么我可能会建议可以执行该操作的代码。

我正在尝试更改原始<td>中的图像为另一张图像(imgx和imgo)。我认为我无法在不获取更改图像时更改图像。 <td> id,而我在更改图像时更改它。也许如果我最初没有在<td>中放置图像,它会起作用,但再次更改id将导致相同的错误? - Mathieu Lussier
@MathieuLussier - 你可以通过获取页面中的图像对象并仅更改其.src属性来更改图像。你不需要使用appendChild() - jfriend00
为什么要踩我?当其他人都不愿回答这个有点难以理解的问题时,我尝试着去解决它。我的回答哪里有错误需要被踩呢? - jfriend00
谢谢你的回答,我找到了解决问题的方法。 - Mathieu Lussier
@MathieuLussier - 这里的协议是,如果你自己找到了一个还没有被其他人提供的答案,那么你应该回答自己的问题。在这里,当你解决了问题后,问题应该有一个答案。当有一个可以解决你问题的答案时,你应该通过点击所需答案左边的绿色复选标记来接受该答案。这将向社区展示你的问题已经得到解答。 - jfriend00

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接