
Enter a search term above to see results...
Enter a search term above to see results...
Semantic provides a standalone library called Query designed from the ground up to work with the Shadow DOM for accessing the DOM, built with modern ECMAScript and browser standards, and tightly coupled into the component framework.
Query provides a chaining interface similar to jQuery for accessing the DOM.
You can do things like create HTML nodes
$('<div />').addClass('test').insertAfter('body');
Retrieve values from the DOM
const html = $('.some-element').html();
and chain expressions similar to jQuery
$('body') .addClass('resizing') .css('cursor', 'resize') .on('pointermove', (event) => { // handle resize });
This section covers only the specific integration of Query inside of components, for a full explaination of the library check out the Query documentation.
Query provides an interface for accessing the DOM you can use to access portions of your component or the page. This is primarily handled by using the $
and $$
exports which are passed through to all lifecycle callbacks in your component.
The $
and $$
arguments are available from lifecycle callbacks and allow you to manipulate the DOM from your component.
$
allows you to retrieve elements without crossing shadow boundaries.
$
naively uses the native querySelectorAll
, which is performant but cannot pierce shadow DOM boundaries. Nodes returned will only be part of the page’s regular DOM. It cannot access nodes that are part of a web component, which are nodes in a shadow DOM tree.
$$
allows you to access any part of the DOM, both the visible DOM and the hidden parts of the DOM accessible from shadow DOM trees.
$
uses the highly performantquerySelectorAll
and is more performant, while$$
requires a custom implementationquerySelectorAllDeep
which recurses through the shadow DOM. It is recommended to use$
for performance unless you need to access nodes that are part of a web component.
In the following example you can see several elements with the class matches
both in the document’s DOM, the web component’s DOM and the DOM slotted to a web component.
You can see that $
matches 2 elements
and $$
matches 3 elements
A common use case is having component functionality that requires accessing some portion of the DOM, to manipulate its contents.
const createComponent = ({el, $}) => ({ startRezize(value) { $('.body').css('cursor', 'resize'); }, endResize() { $('.body').css('cursor', ''); }});
If you need to access the component itself you can use el
.
const createComponent = ({el, $}) => ({ getWidth() { return $(el).width(); }});
If you need to access a nested component you can use $$
Note: This is for DOM access. You can also manipulate a nested component directly using
getChild
and other component traversal helpers.
const createComponent = ({ $$ }) => ({ changeMenuButtonText(text) { return $$('ui-menu ui-button').text(text); }});
You can use $
from onRendered
to immediately manipulate a component, just keep in mind this wont work with ssr.
You can use isServer
or isClient
to determine the location the component is being rendered.
const onRendered = function({isClient, settings, $}) { if(isClient) { $(el).addClass(settings.theme); }};
You can use $
from event handlers to immediately access the element
You can use target
to access the element that matches the selector specified by the event handler.
const events = { 'click .option': function({ $, self, target }) { const color = $(target).computedStyle('background-color'); self.selectColor(color); },});
You can use Query as a standalone library outside of your components, for more information see browser usage
Query provides a few special methods that can be used to manipulate your components from the page.
Query provides a helper getComponent
which can be used to access your components instance from anywhere in the DOM.
This can be used to trigger functionality defined on your component from anywhere in your page. This
// somewhere in your custom codebaseconst selectMenuIndex = (index) => { const menu = $('ui-menu').getComponent(); if(menu) { menu.selectIndex(index); }};
You can use settings
to initialize a component after it is included in the page with settings programatically. This can be particularly useful for components that can be initialized with functions.
$('ui-panel').settings({ getNaturalSize: (panel, { direction, minimized }) => { // some custom logic }});
You can use initialize
to initialize a component with settings before it is included in the page. Initialize can be used before the element it references.
<script>$('ui-panel').initialize({ getNaturalSize: (panel, { direction, minimized }) => { // some custom logic }});</script><ui-panels> <ui-panel>1</ui-panel> <ui-panel>2</ui-panel> <ui-panel>3</ui-panel></ui-panels>
Settings vs Initialize Initialize allows you to include your code to initialize a component anywhere in a page, even before the DOM element it references. This can be useful with some frameworks where
script
blocks may not be processed sequentially or are hoisted.