在日常开发中,现代前端框架已经帮我们处理了大部分元件树和节点属性的更新。不过有时你还是需要直接操作节点,比如控制媒体播放器、操作视图行为、获取节点信息或直接修改样式。
这些功能通常由元件在客户端实现,你需要通过节点引用来访问它们。
让我们尝试一个简单的需求 - 自动滚动页面。我们需要调用 <scroll-view /> 节点的 autoScroll 方法:

这个示例展示了操作节点的两个步骤:使用 useRef 创建引用并通过 ref={scrollRef} 绑定到目标节点,然后在事件处理函数中通过 invoke() 调用节点方法。
ref 获取节点引用如果你熟悉 React,你会发现 ref 的使用方式很相似:
不过要注意,在 Lynx 中节点引用的类型是 NodesRef,这一点和 React 有所不同。如果你想了解更多关于引用的使用技巧,可以参考 Manipulating the Element with Refs。
获取到节点引用后,让我们来看看如何使用它。NodesRef 为你提供了一系列有用的 API。
比如,你可以使用 NodesRef.invoke() 来调用节点的方法。每个元件都会提供一些特定的方法,这些方法在客户端实现并暴露给前端使用。
调用方法时,你可以通过 params 传入方法所需的参数,使用 success 回调处理成功的结果,并用 fail 回调来处理可能的错误。记得在最后调用 exec() 来提交操作,这样才会真正执行:
如果你想要更好的性能和更直观的代码,可以考虑在主线程操作节点。它的优点是操作延迟更低,UI 响应更快,且 API 调用方式更自然。
让我们看看如何在主线程实现同样的功能:

这里的变化主要是:
useMainThreadRef 和 main-thread:ref 来获取主线程的节点引用。MainThread.Element,它提供了多种操作节点的方法。MainThread.Element.invoke() 来调用节点的 autoScroll 方法。除了使用 ref,还可以通过选择器动态获取节点引用。这在需要批量操作节点或动态查找节点时特别有用。
在后台线程中,我们可以使用 SelectorQuery API 来查找节点。让我们看一个例子:

使用选择器很简单:先用 lynx.createSelectorQuery() 创建一个查询对象,然后通过 select() 等方法查找节点。想了解所有支持的选择器,可以查看我们的 API 文档。
在主线程中,事情变得更简单了。你可以使用类似浏览器的 lynx.querySelector() API:

在事件处理场景中,我们经常需要操作触发事件的节点。
在主线程中,你可以直接从事件对象上获取节点引用。和浏览器类似,我们提供了 target 和 currentTarget 属性:

这里我们使用了 MainThread.Element.setStyleProperty() 来修改样式。
getElementById APIgetElementById 是我们目前用于处理动画和 CSS 变量的主要 API。虽然这是一个传统的接口,但在需要执行 JavaScript 动画或想要动态修改 CSS 变量值时,它依然是最好的选择。
想了解更多用法,你可以查看动画 API 文档和 CSS 变量操作指南。我们正在开发更现代的 API 来替代 getElementById,敬请期待。