我想要一个切换文档中元素的按钮。
我不想使用类display:none if / else语句。相反,如果它不存在,我想追加它,如果它存在,那么我想删除孩子。
有一个想法,我想要实现,但我有一些问题。显示了该元素,但是在下一次单击时,它不会被删除,相反,我会获得它的多个副本。 (我认同)。拜托,没有jQuery。仅限香草JavaScript。不知道这很重要,但my-element
是HTML <template>
。
<body>
<button id="my-button">Toggle</button>
<template id="my-element">
<div>
Some content
</div>
</template>
<script>
let element = document.getElementById('my-element');
let content = element.content;
function toggle () {
if (document.body.contains(content)) {
document.body.removeChild(content);
} else {
document.body.appendChild(content);
}
}
let button = document.getElementById('my-button');
button.addEventListener('click', toggle, false);
</script>
</body>
答案 0 :(得分:2)
你应该明白template
存在于加载的DOM之外,所以无论你在代码中的哪个位置,实际上都不会有任何区别。另外,要了解当您要访问template
的内容时,使用.content
,但在将内容注入DOM之后,它不再是template.content
,它是DOM的一部分
因此,您无法在文档中搜索模板.content
,因为在插入后,它不会是文档中的模板内容,而是实际的DOM内容。你需要某种方法来识别它,而类是最简单的方法。
此外, documentation on templates 表示您使用 document.importNode
将模板内容添加到文档中,而您没有使用。
接下来,请始终记住, .removeChild
执行其名称所暗示的内容,它会删除子元素。因此,document.body.removeChild()
只能移除body
元素的子元素,因此您需要记住这一点。您的代码可能可以将导入的节点查找为body
的子节点,但根据您插入的位置,情况可能并非总是如此。下面的代码动态地定位导入内容的父节点,并始终将其删除,无论它最终位于DOM中。
最后,这是非常重要的,虽然你已经表明你不想隐藏/显示元素而宁愿追加并删除它,这样做非常性能昂贵。每次从DOM添加或删除元素时,都必须重建整个DOM,并且删除的节点不一定会从内存中删除,即使它们不再存在于DOM中。因此,这需要您自担风险。实际上,从表演的角度来看,简单地隐藏/展示内容要好得多。
let element = document.getElementById('my-element');
function toggle () {
// Attempt to reference the element in the document, not the template content
var imported = document.querySelector(".imported");
// Check for the element, not the template content
if (document.body.contains(imported)) {
// Element exists, call removeChild on its parent
imported.parentNode.removeChild(imported);
} else {
// Use .importNode to bring template content in:
document.body.appendChild(document.importNode(element.content, true));
}
}
document.getElementById('my-button').addEventListener('click', toggle);
<button id="my-button">Toggle</button>
<template id="my-element">
<div class="imported">Some content</div>
</template>