Skip to content

Instantly share code, notes, and snippets.

@HenrikJoreteg
Last active December 18, 2020 15:34
Show Gist options
  • Save HenrikJoreteg/842629a8efcca05439780a1cfc386e20 to your computer and use it in GitHub Desktop.
Save HenrikJoreteg/842629a8efcca05439780a1cfc386e20 to your computer and use it in GitHub Desktop.
Native virtual dom?
// what if this was something browsers just gave us?
const { vdom } = document;
// this is same idea as React.createElement
// or any of the other similar appraoches
const newVirtualDom = vdom('div', {className: 'some-class'}, [
vdom('p', null, 'hi')
])
// if preferred, someone could easily use JSX and precompile it
// const newVirtualDom = (
// <div className='some-class'>
// <p>hi</p>
// </div>
// )
// then adding a `mutateTo` method to Element.
document.body.mutateTo(newVirtualDom)
@yoavweiss
Copy link

In this scenario, we could also do something like:

document.body.mutateTo("<div class='some-class'><p>hi</p></div>")

@HenrikJoreteg
Copy link
Author

@yoavweiss yes, it could support either. But in your example you run into challenges of knowing whether an element has moved or has been changed in place. Since there's no method in html strings to id an element with a key attribute. But that could also be solved.

@bcomnes
Copy link

bcomnes commented Aug 26, 2017

https://github.com/choojs/nanomorph + https://github.com/shama/bel basically do this. It even supports sibling reordering if the elements have an id attribute.

@bcomnes
Copy link

bcomnes commented Aug 26, 2017

Agreed though, if especially if there was some kind of native API speedup that could be provided by shipping a mutateTo API.

@lukaszpolowczyk
Copy link

What do you think about this?:
`
document.rendered = false;
document.rendered = true;
document.render();
document.render(false);
document.render(true);

document.getElementById("id").rendered = false;
`

Working like documentFragment or display: none. Element is visible but frozen.
Before set element.render(true);, element behavior like maybe body.appendChild(element); or element.style.display = "block";.

Does it contribute to the topic?

@d8corp
Copy link

d8corp commented Nov 12, 2017

customElements.define('my-list', class extends HTMLElement {
    static get observedAttributes() { return ['header', 'items'] }
    constructor () {
      super()
      this.root = this.attachShadow({mode: 'open'})
      this.header = ''
      this.items = []
      this.isRender = false
    }
    connectedCallback() {
      this.isRender = true
      this.render()
    }
    attributeChangedCallback(name, oldValue, newValue) {
      switch (name) {
        case 'header' : {
          this.header = newValue
          break
        }
        case 'items' : {
          this.items = newValue.split(',')
          break
        }
      }
      this.render()
    }
    render () {
      if (this.isRender) {
        this.root.mutateTo(`
          <h1>${this.header}</h1>
          <ul>
            ${this.items.map((item, key) => `<li key="${key}">${item}</li>`).join('')}
          </ul>
        `)
      }
    }
  })

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment