简体   繁体   English

无法将child附加到我的数组中的每个DOM元素?

[英]Can't append child to every DOM element in my array?

Hey friends I have an array of elements. 嘿朋友我有一系列元素。 I want to add a child span element to each one. 我想为每个元素添加一个子span元素。 I used a for loop 我用了一个for循环

for(let i = 0; i < slots.length; i++) {
    //add class to each div
    slots[i].classList.add('c' + i);
    //add the slot to each div
    slots[i].appendChild(slot);
    //add the function with the game logic to each slot
    slots[i].addEventListener('click', runGame); 
}

and watched each element append the child. 并观察每个元素附加孩子。 But when I looked at the elements in my devtools the only element that had a span inside of it was the last one? 但是,当我查看我的devtools中的元素时,唯一具有内部跨度的元素是最后一个? Not all of them? 不是所有的人? Any ideas? 有任何想法吗?

 //grab all slot positions on the board const slots = document.querySelectorAll('.board div'); let player = 'p1'; let board = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, ] let slot = document.createElement('span'); //assign a class to each slot to represent its position for (let i = 0; i < slots.length; i++) { //add class to each div slots[i].classList.add('c' + i); //add the slot to each div slots[i].appendChild(slot); //add the function with the game logic to each slot slots[i].addEventListener('click', runGame); } function runGame() { //figure out which column the selected slot sits in const slotColumn = (Number(this.className.slice(1, 3)) % 7); //create an array to store all the slots that share the above column const columnArray = []; //grab all the slots that sit in that column for (let i = 0; i < board.length; i++) { if (board[i] % 7 === slotColumn) columnArray.push(board[i]); } //drop chip in the chosen column dropChip(columnArray); function dropChip(column) { //select bottom most slot that's available in the column for (let i = column.length - 1; i > 0; i--) { if (column[i] !== 'p1' || column[i] !== 'p2') { board[column[i]] = player; slots[column[i]].classList.add(player); switchPlayer(player); break; } } function switchPlayer(currentPlayer) { if (currentPlayer === 'p1') player = 'p2'; else if (currentPlayer === 'p2') player = 'p1'; } console.log(board); } } 
 /** { outline: 1px solid red; }*/ *, *:before, *:after { box-sizing: inherit; } html { box-sizing: border-box; } html, body { margin: 0; padding: 0; background-color: #e5e6e8; } body { display: flex; justify-content: center; min-height: 100vh; } .board-wrapper { padding-top: 100px; display: flex; justify-content: center; margin: auto auto 0 auto; /*ask why this is needed*/ position: relative; } .board { display: flex; flex-wrap: wrap; max-width: 706px; background-color: #00c; padding: 3px; } .board div { width: 100px; height: 100px; background-color: blue; border: 3px solid #00c; position: relative; } .board div:after { content: ""; display: inline-block; width: 80px; height: 80px; border-radius: 50%; background-color: #00c; position: absolute; left: 0; top: 0; right: 0; bottom: 0; margin: auto; box-shadow: inset 0px 0px 13px #0606aa; } .board .chip { display: block; position: absolute; background-color: transparent; top: 0; left: 0; right: 0; height: 100px; } .board .chip:after { content: ""; width: 80px; height: 80px; border-radius: 50%; background-color: red; position: absolute; left: 3px; top: 0; opacity: 0; transition: all .5s ease; } .board .chip:before { content: ""; width: 50px; height: 50px; border-radius: 50%; background-color: red; position: absolute; left: 18px; top: 15px; z-index: 1; box-shadow: inset 0px 0px 20px #cc0000; opacity: 0; transition: all .5s ease; } .board div:nth-of-type(7n+1):hover~.chip:after { transform: translateX(10px); opacity: 1; } .board div:nth-of-type(7n+1):hover~.chip:before { transform: translateX(10px); opacity: 1; } .board div:nth-of-type(7n+2):hover~.chip:after { transform: translateX(110px); opacity: 1; } .board div:nth-of-type(7n+2):hover~.chip:before { transform: translateX(110px); opacity: 1; } .board div:nth-of-type(7n+3):hover~.chip:after { transform: translateX(210px); opacity: 1; } .board div:nth-of-type(7n+3):hover~.chip:before { transform: translateX(210px); opacity: 1; } .board div:nth-of-type(7n+4):hover~.chip:after { transform: translateX(310px); opacity: 1; } .board div:nth-of-type(7n+4):hover~.chip:before { transform: translateX(310px); opacity: 1; } .board div:nth-of-type(7n+5):hover~.chip:after { transform: translateX(410px); opacity: 1; } .board div:nth-of-type(7n+5):hover~.chip:before { transform: translateX(410px); opacity: 1; } .board div:nth-of-type(7n+6):hover~.chip:after { transform: translateX(510px); opacity: 1; } .board div:nth-of-type(7n+6):hover~.chip:before { transform: translateX(510px); opacity: 1; } .board div:nth-of-type(7n+7):hover~.chip:after { transform: translateX(610px); opacity: 1; } .board div:nth-of-type(7n+7):hover~.chip:before { transform: translateX(610px); opacity: 1; } 
 <div class="board-wrapper"> <div class="board"> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <span class="chip"></span> </div> </div> 

You need to clone the slot element, otherwise it just moves from one parent to the next. 您需要克隆slot元素,否则它只是从一个父元素移动到另一个父元素。

So I added cloneNode() to create a new clone for each location. 所以我添加了cloneNode()为每个位置创建一个新的克隆。

 //grab all slot positions on the board const slots = document.querySelectorAll('.board div'); let player = 'p1'; let board = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, ] let slot = document.createElement('span'); //assign a class to each slot to represent its position for (let i = 0; i < slots.length; i++) { //add class to each div slots[i].classList.add('c' + i); //add the slot to each div slots[i].appendChild(slot.cloneNode()); //<--------------------------- cloneNode() //add the function with the game logic to each slot slots[i].addEventListener('click', runGame); } function runGame() { //figure out which column the selected slot sits in const slotColumn = (Number(this.className.slice(1, 3)) % 7); //create an array to store all the slots that share the above column const columnArray = []; //grab all the slots that sit in that column for (let i = 0; i < board.length; i++) { if (board[i] % 7 === slotColumn) columnArray.push(board[i]); } //drop chip in the chosen column dropChip(columnArray); function dropChip(column) { //select bottom most slot that's available in the column for (let i = column.length - 1; i > 0; i--) { if (column[i] !== 'p1' || column[i] !== 'p2') { board[column[i]] = player; slots[column[i]].classList.add(player); switchPlayer(player); break; } } function switchPlayer(currentPlayer) { if (currentPlayer === 'p1') player = 'p2'; else if (currentPlayer === 'p2') player = 'p1'; } console.log(board); } } 
 /** { outline: 1px solid red; }*/ *, *:before, *:after { box-sizing: inherit; } html { box-sizing: border-box; } html, body { margin: 0; padding: 0; background-color: #e5e6e8; } body { display: flex; justify-content: center; min-height: 100vh; } .board-wrapper { padding-top: 100px; display: flex; justify-content: center; margin: auto auto 0 auto; /*ask why this is needed*/ position: relative; } .board { display: flex; flex-wrap: wrap; max-width: 706px; background-color: #00c; padding: 3px; } .board div { width: 100px; height: 100px; background-color: blue; border: 3px solid #00c; position: relative; } .board div:after { content: ""; display: inline-block; width: 80px; height: 80px; border-radius: 50%; background-color: #00c; position: absolute; left: 0; top: 0; right: 0; bottom: 0; margin: auto; box-shadow: inset 0px 0px 13px #0606aa; } .board .chip { display: block; position: absolute; background-color: transparent; top: 0; left: 0; right: 0; height: 100px; } .board .chip:after { content: ""; width: 80px; height: 80px; border-radius: 50%; background-color: red; position: absolute; left: 3px; top: 0; opacity: 0; transition: all .5s ease; } .board .chip:before { content: ""; width: 50px; height: 50px; border-radius: 50%; background-color: red; position: absolute; left: 18px; top: 15px; z-index: 1; box-shadow: inset 0px 0px 20px #cc0000; opacity: 0; transition: all .5s ease; } .board div:nth-of-type(7n+1):hover~.chip:after { transform: translateX(10px); opacity: 1; } .board div:nth-of-type(7n+1):hover~.chip:before { transform: translateX(10px); opacity: 1; } .board div:nth-of-type(7n+2):hover~.chip:after { transform: translateX(110px); opacity: 1; } .board div:nth-of-type(7n+2):hover~.chip:before { transform: translateX(110px); opacity: 1; } .board div:nth-of-type(7n+3):hover~.chip:after { transform: translateX(210px); opacity: 1; } .board div:nth-of-type(7n+3):hover~.chip:before { transform: translateX(210px); opacity: 1; } .board div:nth-of-type(7n+4):hover~.chip:after { transform: translateX(310px); opacity: 1; } .board div:nth-of-type(7n+4):hover~.chip:before { transform: translateX(310px); opacity: 1; } .board div:nth-of-type(7n+5):hover~.chip:after { transform: translateX(410px); opacity: 1; } .board div:nth-of-type(7n+5):hover~.chip:before { transform: translateX(410px); opacity: 1; } .board div:nth-of-type(7n+6):hover~.chip:after { transform: translateX(510px); opacity: 1; } .board div:nth-of-type(7n+6):hover~.chip:before { transform: translateX(510px); opacity: 1; } .board div:nth-of-type(7n+7):hover~.chip:after { transform: translateX(610px); opacity: 1; } .board div:nth-of-type(7n+7):hover~.chip:before { transform: translateX(610px); opacity: 1; } 
 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Connect Four</title> <link rel="stylesheet" href="style.css"> </head> <body> <div class="board-wrapper"> <div class="board"> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <span class="chip"></span> </div> </div> <script src="script.js"></script> </body> </html> 

I agree with @Mohd Asim Suhail and @Towkir. 我同意@Mohd Asim Suhail和@Towkir。 You can move the creation of slot into the loop. 您可以将slot的创建移动到循环中。 This is fine is all you are doing is creating the slot and not doing anything else to it. 这很好,你正在做的就是创建插槽而不做任何其他操作。 But if you create slot and then add classes and children then it is faster to use cloneNode(true) . 但是如果你创建slot然后添加类和子cloneNode(true)那么使用cloneNode(true)会更快。 ( true will clone all children as well.) true也将克隆所有孩子。)

Given how your example was written I would probably change it to look like this: 鉴于您的示例是如何编写的,我可能会将其更改为如下所示:

 //grab all slot positions on the board const COLUMNS = 7; const ROWS = 7; const boardEl = document.querySelector('.board'); let player = 1; let board = []; boardEl.addEventListener('click', runGame); let c = 0; // Set up the board, assign a class to each slot to represent its position for (let row = 0; row < ROWS; row++) { const newRow = []; for (let col = 0; col < COLUMNS; col++) { newRow.push(0); slot = document.createElement('div'); slot.classList.add('c' + c++); //add class to each div slot.setAttribute('col', col); slot.setAttribute('row', row); slot.innerHTML = '<span></span>'; //add the slot to each div boardEl.appendChild(slot); } board.push(newRow); } const chip = document.createElement('span'); chip.className = 'chip'; boardEl.appendChild(chip); function switchPlayer() { player = player === 1 ? 2 : 1; } function dropChip(col) { const colData = board[col]; //select bottom most slot that's available in the column for (let i = ROWS-1; i >= 0; i--) { if (colData[i] === 0) { colData[i] = player; const el = boardEl.querySelector(`[col="${col}"][row="${i}"]`) el.classList.add(`p${player}`); break; } } switchPlayer(player); } function runGame(evt) { let slot = evt.target; // If they clicked on the `<span>` the move to the `<div>` if (slot.nodeName === 'SPAN') { slot = slot.parentElement; } //figure out which column the selected slot sits in const col = Number(slot.getAttribute('col')); //drop chip in the chosen column dropChip(col); } 
 /** { outline: 1px solid red; }*/ *, *:before, *:after { box-sizing: inherit; } html { box-sizing: border-box; } html, body { margin: 0; padding: 0; background-color: #e5e6e8; } body { display: flex; justify-content: center; min-height: 100vh; } .board-wrapper { padding-top: 100px; display: flex; justify-content: center; margin: auto auto 0 auto; /*ask why this is needed*/ position: relative; } .board { display: flex; flex-wrap: wrap; max-width: 706px; background-color: #00c; padding: 3px; } .board div { width: 100px; height: 100px; background-color: blue; border: 3px solid #00c; position: relative; } .board div:after { content: ""; display: inline-block; width: 80px; height: 80px; border-radius: 50%; background-color: #00c; position: absolute; left: 0; top: 0; right: 0; bottom: 0; margin: auto; box-shadow: inset 0px 0px 13px #0606aa; } .board .chip { display: block; position: absolute; background-color: transparent; top: 0; left: 0; right: 0; height: 100px; } .board .chip:after { content: ""; width: 80px; height: 80px; border-radius: 50%; background-color: red; position: absolute; left: 3px; top: 0; opacity: 0; transition: all .5s ease; } .board .chip:before { content: ""; width: 50px; height: 50px; border-radius: 50%; background-color: red; position: absolute; left: 18px; top: 15px; z-index: 1; box-shadow: inset 0px 0px 20px #cc0000; opacity: 0; transition: all .5s ease; } .board div:nth-of-type(7n+1):hover~.chip:after { transform: translateX(10px); opacity: 1; } .board div:nth-of-type(7n+1):hover~.chip:before { transform: translateX(10px); opacity: 1; } .board div:nth-of-type(7n+2):hover~.chip:after { transform: translateX(110px); opacity: 1; } .board div:nth-of-type(7n+2):hover~.chip:before { transform: translateX(110px); opacity: 1; } .board div:nth-of-type(7n+3):hover~.chip:after { transform: translateX(210px); opacity: 1; } .board div:nth-of-type(7n+3):hover~.chip:before { transform: translateX(210px); opacity: 1; } .board div:nth-of-type(7n+4):hover~.chip:after { transform: translateX(310px); opacity: 1; } .board div:nth-of-type(7n+4):hover~.chip:before { transform: translateX(310px); opacity: 1; } .board div:nth-of-type(7n+5):hover~.chip:after { transform: translateX(410px); opacity: 1; } .board div:nth-of-type(7n+5):hover~.chip:before { transform: translateX(410px); opacity: 1; } .board div:nth-of-type(7n+6):hover~.chip:after { transform: translateX(510px); opacity: 1; } .board div:nth-of-type(7n+6):hover~.chip:before { transform: translateX(510px); opacity: 1; } .board div:nth-of-type(7n+7):hover~.chip:after { transform: translateX(610px); opacity: 1; } .board div:nth-of-type(7n+7):hover~.chip:before { transform: translateX(610px); opacity: 1; } .board span { border-radius: 50%; display: inline-block; height: 80px; left: 10px; position: relative; top: 10px; width: 80px; z-index: 999; } .board .p1 span { background-color: red; } .board .p2 span { background-color: black; } 
 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Connect Four</title> <link rel="stylesheet" href="style.css"> </head> <body> <div class="board-wrapper"> <div class="board"> </div> </div> <script src="script.js"></script> </body> </html> 

This version of the code converts your board into a double-dimension array, only requires one event handler and works, most of the way. 这个版本的代码将您的电路板转换为双维数组,只需要一个事件处理程序,并且大多数情况下都可以工作。

You can just move 你可以移动

let slot = document.createElement('span');

line inside the for loop to solve the problem. for循环内部的行来解决问题。

Refer to this link for further understanding the behavior of appendChild in DOM. 有关进一步了解DOM中appendChild的行为,请参阅此链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM