【问题标题】:Cannot access element after creating it with append child使用附加子项创建元素后无法访问元素
【发布时间】:2022-06-19 22:03:49
【问题描述】:

我正在尝试使用 html 和 js 创建一个国际象棋游戏。

这是我的 HTML 代码的一部分:

<div id="board">
            <div id="1">
                <p name="a" class="white"><img class="icon" id="rw1" src="icons/rookw.png"></p>
                <p name="b" class="black"><img class="icon" id="nw1" src="icons/knightw.png"></p>
                <p name="c" class="white"><img class="icon" id="bw1" src="icons/bishw.png"></p>
                <p name="d" class="black"><img class="icon" id="qw"  src="icons/queenw.png"></p>
                <p name="e" class="white"><img class="icon" id="kw"  src="icons/kingw.png"></p>
                <p name="f" class="black"><img class="icon" id="bw2" src="icons/bishw.png"></p>
                <p name="g" class="white"><img class="icon" id="nw2" src="icons/knightw.png"></p>
                <p name="h" class="black"><img class="icon" id="rw2" src="icons/rookw.png"> </p>
            </div>
            <div id="2">
                <p name="a" class="black"><img class="icon" id="pwa" src="icons/pawnw.png"></p>
                <p name="b" class="white"><img class="icon" id="pwb" src="icons/pawnw.png"></p>
                <p name="c" class="black"><img class="icon" id="pwc" src="icons/pawnw.png"></p>
                <p name="d" class="white"><img class="icon" id="pwd" src="icons/pawnw.png"></p>
                <p name="e" class="black"><img class="icon" id="pwe" src="icons/pawnw.png"></p>
                <p name="f" class="white"><img class="icon" id="pwf" src="icons/pawnw.png"></p>
                <p name="g" class="black"><img class="icon" id="pwg" src="icons/pawnw.png"></p>
                <p name="h" class="white"><img class="icon" id="pwh" src="icons/pawnw.png"></p>
            </div>
            <div id="3">
                <p name="a" class="white"></p>
                <p name="b" class="black"></p>
                <p name="c" class="white"></p>
                <p name="d" class="black"></p>
                <p name="e" class="white"></p>
                <p name="f" class="black"></p>
                <p name="g" class="white"></p>
                <p name="h" class="black"></p>
..........
</div>

这里是 JS

var selector = "";
var pawns = document.querySelectorAll('img');
for (let pawn of pawns) {
    pawn.onclick = select;
}
function select() {
    if (selector != "") {
        document.getElementById(selector).style.backgroundColor = "transparent";
    }
    selector = this.id;
    document.getElementById(selector).style.backgroundColor = "rgba(75, 137, 78, 0.5)";
}
var squares = Array.from(document.querySelectorAll("p")).filter(item => !item.querySelector(".icon"));
for (let square of squares) {
    square.onclick = move;
}
function move() {
    if (selector == "")
    {
        return;
    }
    console.log("yes");
    var initial_img = document.getElementById(selector);
    var img = document.createElement("img");
    img.src = initial_img.src;
    this.appendChild(img);
    document.getElementById(selector).style.backgroundColor = "transparent";
    selector="";
    console.log(img.nodeName);
    //initial_img.remove(img);
}

一切正常,但问题是当我使用 append child 复制图像时,我无法再选择复制的图像。我仍然可以选择原始的。

【问题讨论】:

    标签: javascript html


    【解决方案1】:

    问题是您正在附加一个没有onclick 事件侦听器、id 或类名的新图像。所以你必须将它们添加到新的附加图像中。

    但即使你这样做了,还有另一个问题是图像onclick 和新图像所在正方形的onclick 会同时触发,使图像在原位移动.

    为了以简单的方式解决这两个问题,我建议您只需将move 处理程序添加到所有方格,然后在内部检查当前方格是否有任何子节点。如果是,则返回。

    function move() {
      if (selector == '' || this.children.length) return
      
      ...
    }
    

    当然,如果广场被敌人占领了,您稍后会想添加更多逻辑。

    现在要将图像从一个正方形移动到另一个正方形,您只需将当前选定的图像附加到新正方形,它将从旧正方形中删除,因此无需创建新图像:

     const initial_img = document.getElementById(selector)
     this.appendChild(initial_img)
    

    以下是建议修复的简单可运行示例。 css 和 opacity 的东西只是为了演示:

    let selector = ''
    const pawns = document.querySelectorAll('img')
    const squares = [...document.querySelectorAll('p')]
    
    for (let pawn of pawns) {
      pawn.onclick = select
    }
    
    for (let square of squares) {
      square.onclick = move
    }
    
    function select() {
      if (selector != '') {
        document.getElementById(selector).style.opacity = 1
      }
      selector = this.id
      document.getElementById(selector).style.opacity = 0.5
    }
    
    function move() {
      // If nothing is selected or if the current cell
      // is occupied (its children length is not zero)
      // then just return
      if (selector == '' || this.children.length) return
    
      // Get the selected image and append it to the new
      // square. This will remove the image from the previous
      // square.
      const initial_img = document.getElementById(selector)
      this.appendChild(initial_img)
    
      document.getElementById(selector).style.opacity = 1
      selector = ''
    }
    /* Just for demo */
    
    #board {
      display: grid;
      max-width: 280px;
      background-color: rgb(124, 123, 123);
      grid-template-columns: repeat(auto-fill, minmax(50px, 1fr));
      gap: 1px;
    }
    
    img {
      width: 50px;
      height: 50px;
    }
    
    p {
      margin: 4px 0;
    }
    
    .white {
      background-color: #c2bebe;
      width: 50px;
      height: 50px;
    }
    
    .black {
      background-color: rgb(78, 52, 52);
      width: 50px;
      height: 50px;
    }
    <div id="board">
      <p name="a" class="white">
        <img class="icon" id="rw1" src="https://www.gravatar.com/avatar/ab97b60e45a8b300c0436de98c048633?s=64&d=identicon&r=PG&f=1" />
      </p>
      <p name="b" class="black">
        <img class="icon" id="nw1" src="https://www.gravatar.com/avatar/b0ded36026e886f443a5a5adf371c493?s=48&d=identicon&r=PG" />
      </p>
      <p name="a" class="white"></p>
      <p name="b" class="black"></p>
      <p name="c" class="white"></p>
      <p name="d" class="black"></p>
      <p name="e" class="white"></p>
      <p name="f" class="black"></p>
      <p name="g" class="white"></p>
      <p name="h" class="black"></p>
      <p name="i" class="white"></p>
    </div>

    【讨论】:

    • 当我在查询选择器中选择所有图像时,为什么不能选择附加的新图像。是不是因为代码执行得更早了?
    • @MWD 是的。查询选择器仅选择已经存在的图像,然后单击事件处理程序仅添加到这些图像。使用document.createElement("img"); 创建的新图片没有任何点击事件监听器。
    • 谢谢,它解决了我的问题。但我有一个问题 - 您正在附加孩子,但从未将其从初始方格中移除,为什么它仍然有效?
    • @MWD 这是因为appendChild() 将元素从其原始父元素中移除,然后将其附加到新元素。
    • 好的,谢谢。但是,当我以前使用附加子项时,它并没有删除原件,是因为我创建了原件的副本。当您使用 append child 时,getElement 将原始元素提供给 append child。
    猜你喜欢
    • 2012-12-21
    • 1970-01-01
    • 2011-12-10
    • 1970-01-01
    • 1970-01-01
    • 2011-11-07
    • 2016-11-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多