Core Concepts: Managing the DOM
When writing JavaScript for the browser, you usually need to interact with HTML elements on the page. In traditional web development, you might use document.querySelector('.my-class') or document.getElementById('my-id').
In Coralite, direct DOM querying is typically replaced by the built-in refs plugin. This plugin provides a safe, runtime DOM element targeting system specifically designed for component encapsulation.
Why Use Refs Instead of querySelector? #
- Encapsulation: When you use
document.querySelector, you risk selecting an element outside your component, or selecting an element from a different instance of the same component on the page. - Shadow DOM Compatibility: If you eventually compile your Coralite component into a standalone Web Component, the DOM is encapsulated in a ShadowRoot.
document.querySelectorwon't work across the shadow boundary. The refs plugin automatically handles this scoping for you! - Performance: The refs plugin caches DOM lookups, so subsequent calls to retrieve the same element are instant.
How to Use Refs #
Using the refs plugin is a simple two-step process: defining the reference in your HTML template, and accessing it in your client-side script.
1. Template Setup #
Add a ref="yourName" attribute to any HTML element inside your component's <template>.
During the server-side build, Coralite intercepts this attribute, generates a unique, component-instance-specific ID for the element, and maps it behind the scenes.
<template id="my-form">
<form>
<input type="text" ref="usernameInput" placeholder="Enter username"></input>
<button type="submit" ref="submitBtn">Submit</button>
</form>
</template>
2. Script Usage #
Inside your defineComponent's client.script, the refs plugin provides a helper function: helpers.refs('yourName').
Call this function with the name you defined in the template to retrieve the actual DOM element.
<script type="module">
import { defineComponent } from 'coralite'
export default defineComponent({
client: {
script: (context) => {
// Extract the refs helper from the context
const { helpers } = context
const refs = helpers.refs
// Safe DOM element retrieval
const input = refs('usernameInput')
const button = refs('submitBtn')
// Now use standard DOM APIs
button.addEventListener('click', (e) => {
e.preventDefault()
console.log(`Submitted username: ${input.value}`)
})
}
}
})
</script>
Under the Hood: Scoping & Safety #
The refs plugin is highly context-aware. Depending on how your component is compiled, it behaves differently to ensure maximum safety:
- Shadow DOM Scoping: If your component is compiled as a standalone Web Component, the
contextobject receives arootproperty (the ShadowRoot). The refs plugin detects this and automatically restricts all element lookups to that specific Shadow DOM boundary. Complete encapsulation is guaranteed. - Global Fallback: For standard Server-Side Rendered (SSR) components, the plugin safely scopes the lookup to the instance ID generated during the build.
- Caching: The first time you call
refs('myEl'), it performs the DOM query. If found, the DOM node is cached locally in the plugin. The next time you callrefs('myEl'), it returns immediately without querying the DOM again. - Null Safety: If the element isn't found (perhaps conditionally rendered out), the helper safely returns
nullwithout throwing an error.