Javascript 添加/删除<;模板>;到/从DOM?
我正在尝试为我正在编写的一个小游戏向DOM中添加HTML。我的设计要求首先启动一个主菜单系统,在这个系统中,我希望弹出并删除一组元素 我的问题是,最有效的方法是什么?经过一些研究,我在主体中实现了元素,其中ID表示它们包含的菜单部分。它们看起来像这样:Javascript 添加/删除<;模板>;到/从DOM?,javascript,html,Javascript,Html,我正在尝试为我正在编写的一个小游戏向DOM中添加HTML。我的设计要求首先启动一个主菜单系统,在这个系统中,我希望弹出并删除一组元素 我的问题是,最有效的方法是什么?经过一些研究,我在主体中实现了元素,其中ID表示它们包含的菜单部分。它们看起来像这样: <template id="main"> <div class="wrapper_inner"> <main id="main_screen"> <h
<template id="main">
<div class="wrapper_inner">
<main id="main_screen">
<h1>Main menu</h1>
<nav class="vertical">
<button type="button">Characters</button>
<button type="button">Planets</button>
<button type="button">Export...</button>
<button type="button">Settings</button>
</nav>
</main>
</div>
</template>
更新:问题出在
cloneNode()
函数中。
在传递到正文时创建不可访问的文档片段。如果
有人可以找到解决办法,我会更新最佳答案
然而。。。这在扩展测试中造成了相当大的问题。我确信,我每次只会更改几次菜单,但我希望保持最高的效率。问题出现在这里:
function test()
{
console.log("start test...");
var start = new Date();
for(var i=0; i<10000; i++)
{
menuSystem("main");
}
clearMenu();
console.log("test completed in " + Math.round(((new Date())-start)/1000) + " secs");
}
功能测试()
{
日志(“启动测试…”);
var start=新日期();
对于(var i=0;i大多数情况下,最好显示和隐藏元素,而不是添加和删除它们。因此,只需将元素放入标记中,然后隐藏元素:
document.querySelector("some selector").style.display = "none";
为了证明这一点:
document.querySelector("some selector").style.display = "block";
…或“内联”
或“内联块”
,视情况而定
或者使用类将其隐藏,然后删除该类以再次显示:
CSS:
要隐藏:
document.querySelector("some selector").classList.add("hidden");
显示:
document.querySelector("some selector").classList.remove("hidden");
IE8和IE9(以及一对利基浏览器),但如果你环顾四周,你可以找到一个垫片/多边形填充
旁注1:用于添加元素的代码创建了一个无效的结构,因为您没有从克隆的元素中删除id
,而是将其追加。这意味着文档中有两个元素具有相同的id
,这是无效的。(OP使用的是
元素并附加其内容,而不是它们。仔细看,Teej!)
旁注2:删除菜单项的代码可以通过记住找到的元素而不是调用document.querySelector
两次来加快速度。例如:
function clearMenu()
{
var wrapperInner = document.querySelector('.wrapper_inner');
if(wrapperInner) {
document.body.removeChild(wrapperInner);
}
}
A建议将事情的速度提高一倍(这似乎很明显,但像getElementsByTagName
这样的旧方法就不是这样了)。当然,这只在您看到实际性能问题时才重要,但这就是为什么您要发布…使用文档片段,不要在每次迭代时直接附加到DOM:-而且您可能希望缓存querySelector调用,据我所知,它们是文档片段,不是吗?不,它们仍然是刚刚呈现的DOM元素另外,您正在创建一个新的DOM元素,它不是modalSystem
中的模板,并将其附加到DOM中,因此您仍然没有在那里使用片段。@RGraham:From:“每个template
元素都有一个关联的DocumentFragment
对象,这是它的模板内容。”(他们的重点)这就是OP在上面使用的内容。@RGraham:我看不出有任何理由通过第二个文档片段传递克隆。绝对如此。这当然意味着任何事件处理程序都需要考虑元素是否可以隐藏。@RGraham:确实如此。因此,如果我的HTML中有几个GUI层,那么它的形式不会被认为是不好的在与游戏交互之前,是否需要预先加载并隐藏ave?例如,目前我有三个潜在层(带子层?),如:主菜单层->登录,开始屏幕,角色屏幕,设置屏幕,暂停屏幕| | | |游戏gui层与角色健康等| |在游戏菜单层->库存,容器库存,商店,etc@DanieClawson:“…必须先预加载,然后隐藏…”您可以在隐藏状态下预加载它们(style=“display:none”
在标记上,或使用隐藏它们的类)。关于旁注1:我不知道在使用“关于在隐藏状态下预加载”时会出现问题:我知道,我只是想知道前端是否有大量数据不一定需要在运行时处理。
document.querySelector("some selector").classList.remove("hidden");
function clearMenu()
{
var wrapperInner = document.querySelector('.wrapper_inner');
if(wrapperInner) {
document.body.removeChild(wrapperInner);
}
}