Javascript 添加/删除<;模板>;到/从DOM?

Javascript 添加/删除<;模板>;到/从DOM?,javascript,html,Javascript,Html,我正在尝试为我正在编写的一个小游戏向DOM中添加HTML。我的设计要求首先启动一个主菜单系统,在这个系统中,我希望弹出并删除一组元素 我的问题是,最有效的方法是什么?经过一些研究,我在主体中实现了元素,其中ID表示它们包含的菜单部分。它们看起来像这样: <template id="main"> <div class="wrapper_inner"> <main id="main_screen"> <h

我正在尝试为我正在编写的一个小游戏向DOM中添加HTML。我的设计要求首先启动一个主菜单系统,在这个系统中,我希望弹出并删除一组元素

我的问题是,最有效的方法是什么?经过一些研究,我在主体中实现了元素,其中ID表示它们包含的菜单部分。它们看起来像这样:

<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);
    }
}