代码之家  ›  专栏  ›  技术社区  ›  Chuck Le Butt

无法操作appendChild()创建的元素

  •  0
  • Chuck Le Butt  · 技术社区  · 2 年前

    我在这个上面拔头发。我有一个JavaScript类,它克隆了 <template> 元素,然后附加到文档主体。然后我想操作新创建的元素。。。但它总是坚称它是未定义的。

    样板

    <template id="js-modalTemplate">
        <aside class="o--modal" style="display: none">
            <button class="o-modal__close-button">
                Close
            </button>
            <div><iframe class="js-video" src=""></iframe></div>
        </aside>
    </template>
    

    ES模块

    export default class Modal {
      constructor() {
        const template = document.getElementById('js-modalTemplate');
        const modalTemplate = template.content.cloneNode(true)
    
        this.modalElement = document.body.appendChild(modalTemplate)
    
        console.log(this.modalElement)
    
        this.modalElement.style.display = "block"
      }
    }
    

    Script元素

    <script type="module">
       import VideoModal from "{{ Vite::asset('resources/js/components/Modal.js') }}"
    
       window.testModal = new Modal()
    </script>
    

    元素的console.log输出 有时 完整出现,但是 有时 它是空的(没有更改代码)。。。

    空碎片:

    enter image description here

    包含内容的片段:

    enter image description here

    然而,无论发生什么,我总是会出现以下错误:

    未捕获的类型错误:无法设置未定义的属性(设置“display”)

    并且元素总是出现在DOM中预期的位置。

    我尝试过的东西

    • 将脚本元素移动到的底部 document.body 和添加 defer 。(这两件事都不应该是必要的,因为它无论如何都是ES模块,所以它会自动推迟。)
    • 将代码放置在 window.onload 出于类似的原因

    使用 <模板> 这导致了这个问题,但我以前从未使用过它们,所以我不知道是什么!

    2 回复  |  直到 2 年前
        1
  •  1
  •   Unmitigated    2 年前

    您可以获得顶级元素( <aside> )从碎片到 firstElementChild 然后将其附加到DOM。

    this.modalElement = modalTemplate.firstElementChild;
    document.body.appendChild(modalTemplate);
    
        2
  •  1
  •   Phil    2 年前

    您的问题是模板内容代表 DocumentFragment 。。。

    它被用作Document的轻量级版本,用于存储由节点组成的文档结构的一段

    也就是说,它是内容的容器,而不是内容本身。

    如果要在任何特定节点上操作,如 <aside> ,您需要在片段中定位它。

    例如,使用 firstElementChild 所有物

    const template = document.getElementById("js-modalTemplate");
    
    const content = template.content.cloneNode(true).firstElementChild;
    console.log('style.display:', content.style.display);
    <template id="js-modalTemplate">
      <aside class="o--modal" style="display: none">
        <button class="o-modal__close-button">
          Close
        </button>
        <div><iframe class="js-video" src=""></iframe></div>
      </aside>
    </template>