javascriptes6-moduleshtml-templates

Unable to manipulate element created by appendChild()


I'm pulling my hair out on this one. I have a JavaScript class that clones a <template> element and then is appended to the document body. I want to then manipulate that newly created element... but it always insists it's undefined.

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 Module

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 element

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

   window.testModal = new Modal()
</script>

The console.log output of the element sometimes appears in full, but sometimes it's empty (no changes to code)...

Empty fragment:

enter image description here

Fragment with content:

enter image description here

However I always get the following error, no matter what:

Uncaught TypeError: Cannot set properties of undefined (setting 'display')

And the element always appears in the DOM at the expected place.

Things I've tried

There's just something about using a <template> that causes this issue, but I've never used them before so I don't know what!


Solution

  • You could get the top level element (the <aside>) from the fragment through firstElementChild before appending it to the DOM.

    this.modalElement = modalTemplate.firstElementChild;
    document.body.appendChild(modalTemplate);