HomeDocs
Skip to main content

sjs Event Handling

Background

In Mini Programs, there can be some performance issues when frequently interacting with users. For example, if a page contains two elements, A and B, and the user performs a touchmove gesture on A, requiring B to follow the movement of A. The response process for a single touchmove event is as follows:

  1. The touchmove event is sent from the view layer (Webview) to the logic layer (App Service).
  2. The logic layer (App Service) processes the touchmove event and changes the position of B using setData.

The response to a touchmove event involves two rounds of communication between the logic and rendering layers, as well as one rendering operation. Communication consumes a significant amount of time. Additionally, the rendering performed by setData can block other script execution, resulting in delays in the overall user interaction animation.

Implementation Approach

The basic idea of this approach is to reduce the number of communications and make events respond in the view layer (Webview). Mini Programs are divided into view layers (Webview) and logic layers (App Service). This layered structure is designed for management purposes, where developer code can only run in the logic layer (App Service). However, this approach requires developer code to run in the view layer (Webview), as shown in the following diagram:

SJS Flowchart

The sjs function is used to respond to Mini Program events. Currently, it can only respond to events from built-in components and does not support events from custom components. The sjs function can handle pure logical operations and can also access and set component classes and styles using the pre-packaged ComponentDescriptor instance. For interactive animations, setting styles and classes is sufficient. Here's an example of an sjs function:

var sjsFunction = function (event, ownerInstance) {
var instance = ownerInstance.selectComponent(".classSelector"); // Returns the component instance
instance.setStyle({
"font-size": "14px",
});
instance.getDataset();
instance.setClass(className);
// ...
return false; // Does not propagate upward, equivalent to calling stopPropagation and preventDefault simultaneously
};

The event parameter is an extension of the Mini Program event object with an additional event.instance to indicate the ComponentDescriptor instance of the component that triggered the event. The ownerInstance parameter represents the ComponentDescriptor instance of the component where the event was triggered. If the component triggering the event is on a page, ownerInstance represents the page instance.

Here's the definition of ComponentDescriptor:

MethodParametersDescription
selectComponentselector objectReturns a ComponentDescriptor instance of the component.
setStyleObject/stringSets the component's style. Styles set here have higher priority than those defined in the component's DLT. Cannot set styles for the top-level page.
addClass/removeClass/hasClassstringSets the component's class. Classes set here have higher priority than those defined in the component's DLT. Cannot set classes for the top-level page.
getDataSetNoneReturns the dataset object of the current component/page.
callMethod(funcName: string, args: object)Calls functions defined in the logic layer (App Service) for the current component/page. funcName represents the function name, and args represents the function's parameters.
requestAnimationFrameFunctionSame as the native requestAnimationFrame. Used to set animations.
getComputedStyleArray.<string>Parameters are consistent with SelectorQuery's computedStyle.
setTimeout(Function, Number)Same as the native setTimeout. Used to create timers.
clearTimeoutNumberSame as the native clearTimeout. Used to clear timers.
getBoundingClientRectNoneReturns a value consistent with SelectorQuery's boundingClientRect.

sjs runs in the view layer (Webview), where the available events are limited. Therefore, there needs to be a mechanism to communicate with developer code in the logic layer (App Service). The callMethod method mentioned above allows sjs to call developer code in the logic layer (App Service).

How to Use

  • Define an event with dlt
<import-sjs module="test" src="./test.sjs"></import-sjs>
<view bind:touchmove="{{test.touchmove}}" class="movable"></view>

Note: The sjs function must be enclosed in {{}}.

  • In the test.sjs file, define and export event handling functions and functions triggered by property changes:
export default {
touchmove: function (event, instance) {
var touch = event.touches[0] || event.changedTouches[0];
var pageX = touch.pageX;
var pageY = touch.pageY;
var left = pageX - startX + lastLeft;
var top = pageY - startY + lastTop;
startX = pageX;
startY = pageY;
lastLeft = left;
lastTop = top;

ins.selectComponent(".movable").setStyle({
left: left + "px",
top: top + "px",
});
},
};
Privacy agreementDeveloper agreementcontact us: developer_service.mi@transsion.com © 2024 MiniApp. All Rights Reserved.