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 characters JavaScript 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. Lifecycle diagram of a Modjool element Learn more Diving deep into the reactivity system next!