SJS 响应事件

收藏
我的收藏
基础库 2.75.0 及以上版本开始支持,开发者工具请使用大于等于 4.0.0 的版本,可下载IDE。​

背景​

有频繁用户交互的效果在小程序上表现是比较卡顿的,例如页面有 2 个元素 A 和 B,用户在 A 上做 touchmove 手势,要求 B 也跟随移动。一次 touchmove 事件的响应过程为:​
    1.touchmove 事件从视图层(Webview)抛到逻辑层(App Service)。​
    2.逻辑层(App Service)处理 touchmove 事件,再通过 setData 来改变 B 的位置。​
一次 touchmove 的响应需要经过 2 次的逻辑层和渲染层的通信以及一次渲染,通信的耗时比较大。此外 setData 渲染也会阻塞其它脚本执行,导致了整个用户交互的动画过程会有延迟。​
因此,要支持此种富交互场景,必须减少通信次数,允许在视图层(Webview)直接响应事件。SJS 函数支持响应基础组件的事件,无需数据更新,可直接驱动视图元素的样式、类名等的变更,也可查询元素的布局信息等。​
实现流程图:​

如何使用​

SJS 事件回调​

.sjs 文件中定义函数:​
function handleEvent(event, ownerInstance) { event.instance.setStyle({ "font-size": "14rpx", }); // ... } module.exports = { handleEvent, };
接着,可以在 .ttml 中使用回调:​
<sjs module="test" src="./test.sjs"></sjs> <view bindtouchmove="{{test.handleEvent}}"></view>
支持的事件:ttml 事件。​
同时支持:​
    capture 捕获阶段触发事件​
    stop 阻止冒泡​
    prevent 阻止默认行为​
例如:​
<sjs module="test" src="./test.sjs"></sjs> <view id="module" bindtap.stop="{{test.handleEvent}}"> view2 </view>
入参:​
参数​
描述​
event​
小程序事件对象的基础上增加event.instance 来表示触发事件的组件的 ComponentDescriptor 实例。​
ownerInstance​
内置组件所在自定义组件/页面的 ComponentDescriptor 描述对象。​

SJS 属性监听​

.sjs 文件中定义函数:​
function handlePropChange(newValue, oldValue, ownerInstance, instance) { // ... } module.exports = { handlePropChange, };
接着,可以在 .ttml 中使用回调:​
<sjs module="test" src="./test.sjs"></sjs> <view change:prop="{{test.handlePropChange}}" prop="{{propValue}}"></view>
入参:​
参数​
描述​
newValue​
被监听属性新值​
oldValue​
被监听属性旧值​
ownerInstance​
内置组件所在自定义组件/页面的 ComponentDescriptor 描述对象。​
instance​
内置组件的ComponentDescriptor

ComponentDescriptor 描述对象​

在 SJS 事件回调函数、SJS 属性监听函数中都会传当前元素的ComponentDescriptor与元素所在 Page 或 Componment 的ComponentDescriptor
ComponentDescriptor 具有以下方法:​
方法​
参数​
描述​
selectComponent​
selector​
参数同 SelectorQuery.select返回组件的 ComponentDescriptor 实例。​
selectAllComponents​
selector​
参数同 SelectorQuery.selectAll 返回组件的 ComponentDescriptor 实例数组。​
setStyle​
Object/string​
设置组件样式,支持rpx。设置的样式优先级比组件 ttml 里面定义的样式高。每次调用都会覆盖上一次的调用。不能设置最顶层页面的样式。​
addClass/removeClass/hasClass​
string​
设置组件的 class。设置的 class 优先级比组件 ttml 里面定义的 class 高。不能设置最顶层页面的 class。不能操作 tt-* 内置样式。​
getDataset​
-​
返回当前组件/页面的 dataset 对象。​
callMethod​
(funcName:string, args:object)​
调用当前组件/页面在逻辑层(App Service)定义的函数。funcName表示函数名称,args表示函数的参数。​
triggerEvent​
(eventName, detail)​
和组件的 triggerEvent 一致。只能在自定义组件上触发。​
requestAnimationFrame​
Function​
和原生 requestAnimationFrame 一样。用于设置动画。​
getState​
-​
返回一个 object 对象,当有局部变量需要存储起来后续使用的时候用这个方法。​
getComputedStyle​
Array.<string>​
返回值与 NodesRef.fieldscomputedStyle 一致。​
setTimeout​
与原生 setTimeout 一致。用于创建定时器。​
clearTimeout​
与原生 clearTimeout 一致。用于清除定时器。​
getBoundingClientRect​
-​
返回值与 NodesRef.boundingClientRectboundingClientRect 一致。​

Bug & Tip​

    Tip:使用 SJS 函数必须使用 {{}} 括起来。​
    Tip:使用 SJS 属性监听时,内置组件初始化时会立即回调一次监听函数。当被监听属性值更新后,即新旧值不相等时,会再次触发回调。