在 Javascript 中有没有一种方法可以复制 HTML 包装器而不使其 "Event Listeners" 失去其功能?
Within Javascript is there a way to duplicate an HTML wrapper without its "Event Listeners" losing their functionality?
所以在我的 Javascript 中,我只能复制我的 HTMl Id="characters" 包装器一次。我知道它在技术上应该是一个“class”而不是一个“Id”,因为它将是一个重复的“Id”,但出于某种原因我没有得到;当我将“getElementById”更改为“getElementsByClassName”并将我的 HTML“Id”更改为“class”时,它根本不会重复。也因为我正在使用 clone.Node(true),所以我在重复的包装器中失去了我的“addEventListeners”的功能。有没有办法只使用香草 Javascript 来纠正这个问题?好像这还不够烦人,我的重复包装器似乎将自己从我的 CSS 网格中删除了。这一切都非常乏味和麻烦,所以我感谢你给我的任何建议。
这是我现在的 HTML。
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="css/style.css">
<h1><!--D&D DM Tool--><h1>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title></title>
</head>
<body>
<div id="header-container">
<h1 id="header">Game Tools</h1>
</div>
<div class="importantbuttons">
<button id="resetbutton">Next Round</button>
<button id="orderbutton">Order</button>
<button id="zerobutton">Zero</button>
<button id="deadremoverbtn">Bring Out the Dead!</button>
<button id="addnpcbtn">Add NPC</button>
</div>
<div id="grid">
<div class="characters">
<div id="subgrid" class="subgrid" >
<div class="name-bloodiedstuff">
<div class="halfWayDown"></div>
<div class="character-name-display">Name</div>
<button class="name-submit-btn">Submit</button>
<input type="text" class="input-name-el" placeholder="Name">
<div class=int-stuf>
<div class="roll-display">Iniative</div>
<button class="iniativebtn">Submit</button>
<input type="number" class="iniative-roll-el" placeholder="Iniative Roll">
</div>
<div class="healthpoints-display">Healthpoints</div>
<button class="hp-submit-btn">Submit</button>
<input type="number" class="input-hp-el" placeholder="Total HealthPoints">
<button class="hp-deductin-btn">Submit</button>
<input type="number" class="input-hp-deduction-el" placeholder="Damage">
</div>
<div class="weapons-display">Weapons</div>
<button class="weapon-btn">Submit</button>
<input type="text" class="weapon-input-el" placeholder="Weapons">
<button class="active-btn" class="button">Active</button>
</div>
</div>
</div>
</body>
<script src="mainCopy.js"></script>
</html>
这是我当前的 Javascript 复制函数。
addNpcBtn.addEventListener("click",function(){
var characterSubGrids=document.getElementsByClassName("characters");
console.log(characterSubGrids[0]);
var characterSubGridsClone=characterSubGrids[0].cloneNode(true);
let grid=document.getElementById("grid");
console.log(grid);
grid.appendChild(characterSubGridsClone);
});
From the MDN article on cloneNode
Cloning a node copies all of its attributes and their values, including intrinsic (inline) listeners. It does not copy event listeners added using addEventListener() or those assigned to element properties (e.g., node.onclick = someFunction).
似乎 cloneNode
可能已经忽略了您试图忽略的事件侦听器。
如果您尝试以一种将事件侦听器保留在其 <button>
子级上的方式克隆 <div>
,我认为 DOM 没有用于那。相反,您必须将相同的事件侦听器附加到新的克隆按钮。类似于以下内容:
// Fetch the container and save that element as a constant for future use
const container = document.querySelector('#container')
// Create the addHandlers function for future use
function addHandlers (span) {
// Find the first button child of the element provided as first parameter
const button = span.querySelector('button')
// Add a click event listener to that button
button.addEventListener('click', () => {
// On click, clone the parent element (the span, not the button)
const clone = span.cloneNode(true)
// Find the first input child of this new clone
const input = clone.querySelector('input')
// Set its value to the empty string (by default, the clone would conserve the value of the original)
input.value = ''
// Add handlers to the clone which were lost during cloning
addHandlers(clone)
// Add the clone into the DOM as a new, last child of the container
container.appendChild(clone)
}, false)
}
// Find all elements with class name 'duplicatable' and run the `addHandlers` function on each element
document.querySelectorAll('.duplicatable').forEach(addHandlers)
<div id="container">
<h2>Characters</h2>
<span class="duplicatable">
<button>Add a new character</button>
<input type='text' placeholder='name' />
</span>
</div>
所以在我的 Javascript 中,我只能复制我的 HTMl Id="characters" 包装器一次。我知道它在技术上应该是一个“class”而不是一个“Id”,因为它将是一个重复的“Id”,但出于某种原因我没有得到;当我将“getElementById”更改为“getElementsByClassName”并将我的 HTML“Id”更改为“class”时,它根本不会重复。也因为我正在使用 clone.Node(true),所以我在重复的包装器中失去了我的“addEventListeners”的功能。有没有办法只使用香草 Javascript 来纠正这个问题?好像这还不够烦人,我的重复包装器似乎将自己从我的 CSS 网格中删除了。这一切都非常乏味和麻烦,所以我感谢你给我的任何建议。
这是我现在的 HTML。
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="css/style.css">
<h1><!--D&D DM Tool--><h1>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title></title>
</head>
<body>
<div id="header-container">
<h1 id="header">Game Tools</h1>
</div>
<div class="importantbuttons">
<button id="resetbutton">Next Round</button>
<button id="orderbutton">Order</button>
<button id="zerobutton">Zero</button>
<button id="deadremoverbtn">Bring Out the Dead!</button>
<button id="addnpcbtn">Add NPC</button>
</div>
<div id="grid">
<div class="characters">
<div id="subgrid" class="subgrid" >
<div class="name-bloodiedstuff">
<div class="halfWayDown"></div>
<div class="character-name-display">Name</div>
<button class="name-submit-btn">Submit</button>
<input type="text" class="input-name-el" placeholder="Name">
<div class=int-stuf>
<div class="roll-display">Iniative</div>
<button class="iniativebtn">Submit</button>
<input type="number" class="iniative-roll-el" placeholder="Iniative Roll">
</div>
<div class="healthpoints-display">Healthpoints</div>
<button class="hp-submit-btn">Submit</button>
<input type="number" class="input-hp-el" placeholder="Total HealthPoints">
<button class="hp-deductin-btn">Submit</button>
<input type="number" class="input-hp-deduction-el" placeholder="Damage">
</div>
<div class="weapons-display">Weapons</div>
<button class="weapon-btn">Submit</button>
<input type="text" class="weapon-input-el" placeholder="Weapons">
<button class="active-btn" class="button">Active</button>
</div>
</div>
</div>
</body>
<script src="mainCopy.js"></script>
</html>
这是我当前的 Javascript 复制函数。
addNpcBtn.addEventListener("click",function(){
var characterSubGrids=document.getElementsByClassName("characters");
console.log(characterSubGrids[0]);
var characterSubGridsClone=characterSubGrids[0].cloneNode(true);
let grid=document.getElementById("grid");
console.log(grid);
grid.appendChild(characterSubGridsClone);
});
From the MDN article on cloneNode
Cloning a node copies all of its attributes and their values, including intrinsic (inline) listeners. It does not copy event listeners added using addEventListener() or those assigned to element properties (e.g., node.onclick = someFunction).
似乎 cloneNode
可能已经忽略了您试图忽略的事件侦听器。
如果您尝试以一种将事件侦听器保留在其 <button>
子级上的方式克隆 <div>
,我认为 DOM 没有用于那。相反,您必须将相同的事件侦听器附加到新的克隆按钮。类似于以下内容:
// Fetch the container and save that element as a constant for future use
const container = document.querySelector('#container')
// Create the addHandlers function for future use
function addHandlers (span) {
// Find the first button child of the element provided as first parameter
const button = span.querySelector('button')
// Add a click event listener to that button
button.addEventListener('click', () => {
// On click, clone the parent element (the span, not the button)
const clone = span.cloneNode(true)
// Find the first input child of this new clone
const input = clone.querySelector('input')
// Set its value to the empty string (by default, the clone would conserve the value of the original)
input.value = ''
// Add handlers to the clone which were lost during cloning
addHandlers(clone)
// Add the clone into the DOM as a new, last child of the container
container.appendChild(clone)
}, false)
}
// Find all elements with class name 'duplicatable' and run the `addHandlers` function on each element
document.querySelectorAll('.duplicatable').forEach(addHandlers)
<div id="container">
<h2>Characters</h2>
<span class="duplicatable">
<button>Add a new character</button>
<input type='text' placeholder='name' />
</span>
</div>