Lifecycle events
Lifecycle events are called through a series of convenient hooks,
allowing you to run JavaScript at various
points within a custom element's lifecycle.
General usage
The js hook is normally the only hook you'll need. It runs after the body of the
element has been rendered to the DOM, and it'll update the element's DOM afterwards,
if the element has changed. Here's an example of it in use:
modjool.create({
tag: 'twenty-chars',
js: ({ data, slotVal }) => {
if (slotVal.length > 20) {
data.text = slotVal.slice(0, 20) + '…'
}
},
html: ({ data, slot }) => `
${data.text || slot}
`
})
This element checks whether the slot character length is more than 20, and if it is,
cuts its down to 20 characters, adds '…' to the end, and outputs this instead of the slot.
<twenty-chars>13 characters</twenty-chars>13 characters<twenty-chars>This element contains more than twenty characters</twenty-chars>This element contains more than twenty charactersJavaScript before rendering
The ready hook is invoked one time when the element is initialised. This is before the
element is rendered to the DOM for the first time (and before the js hook is called).
It can be used when the contents of the rendered element body aren't needed in the hook.
ready: ({ elem }) => {
// '' (empty string)
console.log(elem.innerHTML)
},
js: ({ elem }) => {
// 'Hello'
console.log(elem.innerHTML)
},
html: () => `
Hello
`
Note: elem returns the HTMLElement object of the current element
instance, similarly to querySelector.
Event listeners
The DOM is sometimes updated after the js hook is run, meaning that the state of
its child elements can be lost. This means that, for example, event listeners will no longer work
if defined in the js hook, if the body is updated again.
js: ({ data, elem }) => {
// Reactive data has changed, html template will refresh after js hook
data.count = 0
// Event listener will be lost when template refreshed
elem.onmouseover = () => data.count++
},
html: ({ data }) => `
${data.count}
`What do I do?
The complete hook solves this problem; it runs after js,
after the DOM has been rendered, and the body will not change afterwards:
modjool.create({
tag: 'mouseover-listener',
// Reactive data updates template body after js hook
js: ({ data }) => {
data.count = 0
},
// Body does not refresh after complete hook, event listener kept
complete: ({ data, elem }) => {
elem.onmouseover = () => data.count++
},
html: ({ data }) => `
Mouseover count: ${data.count}
`
})
This element increments data.count on mouseover, and outputs it.
<mouseover-listener></mouseover-listener>
It's important to note that the complete hook is also called after
an attribute change hook has been invoked, see the diagram below.
Non-reactive
As we know, any synchronous code within complete
is non-reactive, meaning that the body will never update after invoking the lifecycle event.
However, asynchronous code is reactive, meaning that using events,
timeouts etc will still result in reactive data and attributes. More on this on the
next page.
More hooks
There are more hooks available to use within Modjool, for example the
attr_[name] hook, and the
data_[property] hook.
Try typing "lifecycle event" in the search bar for more information from the Modjool Docs API,
or take a look at the lifecycle diagram below.
Lifecycle diagram
This is the full Modjool lifecycle diagram, detailing initialisation,
reactive data & attr changes, and termination.
All lifecycle hooks in the diagram are represented by green boxes.
Learn more
Diving deep into the reactivity system next!