In daily development, modern front-end frameworks handle most element tree and node property updates for us. However, there are times when you need to manipulate elements directly, such as controlling media players, manipulating view behavior, getting element information, or directly modifying styles.
These functionalities are typically implemented by components on the client side, and you need to access them through element references.
Let's try a simple requirement - auto-scrolling the page. We need to call the autoScroll
method of the <scroll-view />
element:
This example demonstrates two steps for manipulating elements: creating a reference using useRef
and binding it to the target element using ref={scrollRef}
, then calling the element method using invoke()
in the event handler.
ref
If you're familiar with React, you'll find that using ref
is very similar:
However, note that in Lynx, the type of node reference is NodesRef
, which is different from React. If you want to learn more about using references, you can refer to Manipulating the Element with Refs.
After obtaining a node reference, let's see how to use it. NodesRef
provides a series of useful APIs.
For example, you can use NodesRef.invoke()
to call the element's methods. Each component provides specific methods that are implemented on the client side and exposed for front-end use.
When calling a method, you can pass required parameters through params
, handle successful results using the success
callback, and handle potential errors using the fail
callback. Remember to call exec()
at the end to submit the operation for actual execution:
If you want better performance and more intuitive code, you can consider manipulating elements in the main thread. It offers lower operation latency with faster UI response and more natural API calls.
Let's see how to implement the same functionality in the main thread:
The main changes here are: node operations need to be written in main thread functions; using useMainThreadRef
and main-thread:ref
to get the main thread node reference; the node reference type becomes MainThread.Element
, which provides various methods for manipulating nodes; and we used MainThread.Element.invoke()
to call the node's autoScroll
method.
In certain scenarios, such as when you need to batch operate on elements or dynamically find elements, using selectors can be particularly useful.
In the background thread, we can use the SelectorQuery
API to find elements. Let's look at an example:
Using selectors is simple: first create a query object using lynx.createSelectorQuery()
, then use methods like select()
to find elements. To learn about all supported selectors, you can check our API documentation.
When manipulating elements in the main thread, things become even simpler. You can use the browser-like lynx.querySelector()
API:
When handling events, we often need to manipulate the element that triggered the event.
In the main thread, you can get the element reference directly from the event object. Similar to browsers, we provide target
and currentTarget
properties:
Here we used MainThread.Element.setStyleProperty()
to modify styles.
getElementById
APIgetElementById
is currently our main API for handling animations and CSS variables. Although this is a traditional interface, it's still the best choice when you need to execute JavaScript animations or dynamically modify CSS variable values.
To learn more about usage, you can check Animation API documentation and CSS Variables Operation Guide. We are developing more modern APIs to replace getElementById
, stay tuned.