Search code examples
javascriptcustom-element

Creating custom node to extend HTMLIFrameElement


Is it possible to create a custom element like : "" and this new element will have all the functionality of an iframe element? (its own document/window objects and such...) ?


Solution

  • Extending <iframe>

    To extend a standard HTML element, you must use the { extends: "element" } in the customElements.define() method:

    class MyFrame extends HTMLIFrameElement {
        constructor () {
            super()
            console.log( 'created')
        }
    }
    customElements.define( 'my-frame', MyFrame, { extends: 'iframe' } )
    

    Then use the is="custom-element" attribute to create the extended element:

    <iframe is='my-frame'></iframe>
    

    You can then use it as a standard <iframe> and add your custom features.


    Defining a new HTML tag

    Alternaltey, if you want a new tag name, create an autonomous custom element (derived from HTMLElement) with a standard <iframe> element inside :

    class NewFrame extends HTMLElement {
      constructor() {
        super()
        console.log( 'created' ) 
        this.attachShadow( { mode: 'open' } )
            .innerHTML = "<iframe></iframe>"
      }
      connectedCallback() {
        setTimeout( () =>
          this.shadowRoot.querySelector( 'iframe' ).contentDocument.body.innerHTML = this.innerHTML
        )
      }
    }
    customElements.define( 'new-frame', NewFrame )
    

    In this example, the custom element will use the content of the <new-frame> to populate the <iframe> document.

    <new-frame>Hello world !</new-frame>
    

    The drawback of this solution is that your new element won't act as an <iframe>. You'll have to define some custom methods for all the feature you want to forward to the <iframe> inside.