智能小程序事件系统——SJS响应事件实现方案

news2024/12/23 15:18:30

背景信息

如有频繁用户交互,在小程序上表现是比较卡顿的。例如,页面有 2 个元素 A 和 B,用户在 A 上做 touchmove 手势,要求 B 也跟随移动,movable-view 就是一个典型的例子。一次 touchmove 事件的响应过程为:

  1. touchmove 事件从视图层(Webview)抛到逻辑层(App Service)。

  2. 逻辑层(App Service)处理 touchmove 事件,再通过 setData 来改变 B 的位置。

一次 touchmove 的响应需要经过 2 次逻辑层和渲染层的通信以及一次渲染,通信的耗时比较大。此外,setData 渲染也会阻塞其它脚本执行,导致整个用户交互的动画过程出现延迟。

实现方案

本方案基本的思路是减少通信次数,让事件在视图层(Webview)响应。小程序的框架分为视图层(Webview)和逻辑层(App Service)。这样分层的目的是管控,开发者的代码只能运行在逻辑层(App Service),而这个思路就必须要让开发者的代码运行在视图层(Webview),如下图所示的流程:

使用 SJS 函数用来响应小程序事件,目前只能响应内置组件的事件,不支持自定义组件事件。SJS 函数除了纯逻辑的运算,还可以通过封装好的 ComponentDescriptor 实例来访问以及设置组件的 class 和样式。对于交互动画,设置 style 和 class 足够了。SJS 函数的例子如下:

const sjsFunction = function (event, ownerInstance) {
  const instance = ownerInstance.selectComponent('.classSelector'); // 返回组件的实例
  instance.setStyle({
    'font-size': '14px',
  });
  instance.getDataset();
  instance.setClass(className);
  // ...
  return false; // 不往上冒泡,相当于同时调用了 stopPropagation 和 preventDefault
};

其中,入参 event 是小程序事件对象基础上多了 event.instance,来表示触发事件的组件的 ComponentDescriptor 实例。ownerInstance 表示的是触发事件的组件所在组件的 ComponentDescriptor 实例。如果触发事件的组件是在页面内的,ownerInstance 表示的是页面实例。

ComponentDescriptor 的定义如下:

方法参数描述
selectComponentselector 对象返回组件的 ComponentDescriptor 实例。
selectAllComponentsselector 对象数组返回组件的 ComponentDescriptor 实例数组。
setStyleObject/string设置组件样式。设置的样式优先级高于组件 tyml 里面定义的样式。不能设置最顶层页面的样式。

addClass/removeClass

/hasClass

string设置组件的 class。设置的 class 优先级高于组件 tyml 里面定义的 class。不能设置最顶层页面的 class
getDataset返回当前组件或者页面的 dataset 对象。
callMethod(funcName:string, args:object)调用当前组件或者页面在逻辑层(App Service)定义的函数。funcName 表示函数名称,args 表示函数的参数。
requestAnimationFrameFunction和原生 requestAnimationFrame 一样。用于设置动画。
getState返回一个 object 对象。当局部变量需要存储起来,以便后续使用的时候,可以用这个方法。
triggerEvent(eventName, detail)和组件的 triggerEvent 一致。
getComputedStyleArray.<string>参数与 SelectorQuery 的 computedStyle 一致。
setTimeout(Function, Number)与原生 setTimeout 一致。用于创建定时器。
clearTimeoutNumber与原生 clearTimeout 一致。用于清除定时器。
getBoundingClientRect返回值与 SelectorQuery 的 boundingClientRect 一致。

SJS 运行在视图层(Webview),里面的逻辑毕竟能做的事件比较少,需要有一个机制和逻辑层(App Service)开发者的代码通信。上面的 callMethod 是 SJS 里面调用逻辑层(App Service)开发者的代码的方法,而 SjsPropObserver 是逻辑层(App Service)开发者的代码调用 SJS 逻辑的机制。

使用方法

tyml 定义事件:

<sjs module="test" src="./test.sjs"></sjs>

<view change:prop="{{test.propObserver}}" prop="{{propValue}}" bind:touchmove="{{test.touchmove}}" class="movable"></view>

上面的 change:prop(属性前面带 change: 前缀)是在 prop 属性被设置的时候触发 SJS 函数,值必须用 {{}} 括起来。类似 Component 定义的 properties 里面的 observer 属性,在 setData({propValue: newValue}) 调用之后会触发。

注意:SJS 函数必须用 {{}} 括起来。当 prop 的值被设置时,SJS 函数就会触发,而不只是值发生改变。所以在页面初始化时,会调用一次 SjsPropObserver 的函数。

SJS 文件 test.sjs 里面定义并导出事件处理函数和属性改变触发的函数:

// event:事件对象。
// ownerInstance:表示的是触发事件的组件所在组件的 ComponentDescriptor 实例。如果触发事件的组件是在页面内的,ownerInstance 表示的是页面实例。
const touchmove = function (event, ownerInstance) {
  console.log('log event', JSON.stringify(event));
};
 
// newValue:新值。
// oldValue:旧值。
// ownerInstance:表示的是触发事件的组件所在组件的 ComponentDescriptor 实例。如果触发事件的组件是在页面内的,ownerInstance 表示的是页面实例。
// instance:表示触发事件的组件的 ComponentDescriptor 实例。
const propObserver = function (newValue, oldValue, ownerInstance, instance) {
  console.log('prop observer', newValue, oldValue);
};
 
export default {
  touchmove: touchmove,
  propObserver: propObserver,
};

立即开发。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1422810.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java+springboot校园体育场地预约预订使用系统vue+ssm

研究内容和研究方法 1.研究内容 网站主要包括管理员和用户两个部分&#xff0c;用户可以登录与注册自己的基本信息、查询哪些场地可以使用、提前预约场地、取消预约的场地、使用完场地后进行缴费。管理员可以审批用户的注册信息、对用户信息进行增删改查、查询场地的使用情况、…

5G智慧钢铁厂数字孪生三维可视化,推进钢铁新型工业化数字化转型

5G智慧钢铁厂数字孪生三维可视化&#xff0c;推进钢铁新型工业化数字化转型。随着科技的不断发展&#xff0c;数字化转型已经成为钢铁企业转型升级的必经之路。而5G技术的广泛应用&#xff0c;为钢铁企业数字化转型提供了新的机遇。其中&#xff0c;5G智慧钢铁厂数字孪生三维可…

基于ssm和微信小程序的健身房私教预约管理系统

文章目录 项目介绍主要功能截图&#xff1a;部分代码展示设计总结项目获取方式 &#x1f345; 作者主页&#xff1a;超级无敌暴龙战士塔塔开 &#x1f345; 简介&#xff1a;Java领域优质创作者&#x1f3c6;、 简历模板、学习资料、面试题库【关注我&#xff0c;都给你】 &…

计算机设计大赛 垃圾邮件(短信)分类算法实现 机器学习 深度学习

文章目录 0 前言2 垃圾短信/邮件 分类算法 原理2.1 常用的分类器 - 贝叶斯分类器 3 数据集介绍4 数据预处理5 特征提取6 训练分类器7 综合测试结果8 其他模型方法9 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 垃圾邮件(短信)分类算…

亚马逊、eBay、速卖通等跨境电商自养号测评,你知道多少?

在跨境电商领域&#xff0c;自养号测评已经成为常态。大部分卖家都会进行店铺产品的测评&#xff0c;尽管平台和消费者对此持反感态度。但在竞争激烈的环境下&#xff0c;不进行测评就意味着可能被市场淘汰。 过去&#xff0c;在某些论坛上&#xff0c;我曾看到一些博主分享他…

java代码中调用自定义函数

定义函数 CREATE DEFINERrootlocalhost FUNCTION test_fun1(num1 FLOAT,num2 FLOAT) RETURNS float BEGINDECLARE SUM FLOAT DEFAULT 0;SET SUMnum1num2;RETURN SUM; END <select id"cunchu" resultType"java.util.Map">SELECT test_fun1(1,2) as r…

React通用后台模板

一. 项目初始化 1. 创建项目 环境 npm init vite 打开package.json,参考以下各模块版本: "dependencies": { "react": "^18.2.0", "react-dom": "^18.2.0", "react-redux": "^7.2.8", …

Python学习从0到1 day10 Python数据容器.1.列表

我一直相信 ——24.1.27 一、数据容器的定义 1.Python中的数据容器&#xff1a; 一种可以容纳多份数据的数据类型&#xff0c;容纳的每一份数据称之为1个元素&#xff0c;每一个元素&#xff0c;可以是任意类型的数据&#xff0c;如字符串、数字、布尔等 2.数据容器的分类 数据…

[docker] Docker容器服务更新与发现之consul

一、consul的相关知识 1.1 什么是注册与发现 服务注册与发现是微服务架构中不可或缺的重要组件。起初服务都是单节点的&#xff0c;不保障高可用性&#xff0c;也不考虑服务的压力承载&#xff0c;服务之间调用单纯的通过接口访问。直到后来出现了多个节点的分布式架构&#…

第十四届蓝桥杯大赛软件赛省赛(C/C++ 大学B组)题解

尝试再做一次&#xff0c;我记得还是有点难&#xff0c;我会尽量多写一点解析&#xff0c;尽量让基础比较弱的友友也能看懂&#xff0c;希望能给你带来帮助 目录 1. 日期统计 题目描述 解题思路 具体代码 2. 01 串的熵 题目描述 解题思路 具体代码 3. 冶炼金属 题目…

性价比高的蓝牙运动耳机推荐,公认好用的运动耳机品牌推荐

​随着人们对健康的重视&#xff0c;越来越多的人选择加入运动行列。然而&#xff0c;独自运动可能会让人感到乏味&#xff0c;因此许多人在运动时都会选择佩戴运动耳机&#xff0c;让音乐伴随整个运动过程。那么&#xff0c;如何挑选适合自己的运动耳机呢&#xff1f;今天我为…

2024美赛数学建模E题思路+代码

文章目录 1 赛题思路2 美赛比赛日期和时间3 赛题类型4 美赛常见数模问题5 建模资料 1 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 2 美赛比赛日期和时间 比赛开始时间&#xff1a;北京时间2024年2月2日&#xff08;周五&#xff…

【Docker】在Windows下使用Docker Desktop创建nginx容器并访问默认网站

欢迎来到《小5讲堂》&#xff0c;大家好&#xff0c;我是全栈小5。 这是《Docker容器》序列文章&#xff0c;每篇文章将以博主理解的角度展开讲解&#xff0c; 特别是针对知识点的概念进行叙说&#xff0c;大部分文章将会对这些概念进行实际例子验证&#xff0c;以此达到加深对…

品牌运营如何打造出独特的风格?

在上网冲浪日益普遍&#xff0c;在线营销失去神秘的当下&#xff0c;品牌如果一味强调人设&#xff0c;只会浪费宣传成本。从老钱风、静奢风的兴起到多巴胺、美拉德的流行&#xff0c;后消费时代的运营需要注重风格的独特化&#xff0c;与消费者进行真诚沟通&#xff0c;今天媒…

vue3开发,axios发送请求是携带params参数的避坑

vue3开发,axios发送请求是携带params参数的避坑&#xff01;今天一直报错&#xff0c;点击新增购物车&#xff0c;报错&#xff0c; 【Uncaught (in promise) TypeError: target must be an object】。查询了网上的资料说的都不对。都没有解决。最终还是被我整明白了。 网上网…

项目实战:一个基于标准库的具备最值获取的万能容器实现

目录 写在前面 需求 分析 接口设计 项目实现 一些思考与总结 致谢 写在前面 刚刚介绍了变参模板和完美转发&#xff0c;现在换一换脑子做一个小的项目实战吧。博主最近学习的是标准库&#xff0c;总体来说&#xff0c;我认为标准库中的内容是很trivial的&#xff0c;重点…

蓝桥杯 第 1 场 小白入门赛

目录 1.蘑菇炸弹 2.构造数字 3.小蓝的金牌梦 4.合并石子加强版 5.简单的LIS问题 6.期望次数 1.蘑菇炸弹 我们直接依照题目 在中间位置的数进行模拟即可 void solve(){cin>>n;vector<int> a(n1);for(int i1;i<n;i) cin>>a[i];int ans0;for(int i2;i…

uniapp底部栏设置未读红点或角标

pages.json {... // 省略"tabBar": {"color": "#333333","selectedColor": "#3296fa","backgroundColor": "#ffffff","borderStyle": "white","list": [{"pagePat…

【Go】Viper读取配置文件

go get github.com/spf13/viper 1. 设置配置文件的信息 etcd:ip: "192.168.6.106"port: 2379dialTimeout: 3redis:ip: "192.168.6.107"port: 6379password: "root1028"2. 读取配置文件的信息 2.1 通过kv的方式 package mainimport ("fm…

【Tomcat与网络5】再论Tomcat的工作过程与两种经典的设计模式

前面两篇&#xff0c;我们重点分析了Tomcat的容器和连接器的基本设计&#xff0c;今天我们来看一下两个机构如何在service的调度下进行协同工作的。 目录 1.模板模式与Tomcat的重用性设计 2.观察者模式与Tomcat可扩展性设计 1.模板模式与Tomcat的重用性设计 首先&#xff0…