1# JavaScript 2 3 4You can use a .js file in the ECMAScript compliant JavaScript language to define the service logic of an HML page. With dynamic typing, JavaScript can make your application more expressive with a flexible design. The following describes the JavaScript compilation and running. 5 6 7## Syntax 8 9The ES6 syntax is supported. 10 11- Module declaration 12 13 Import functionality modules. 14 15 ```js 16 import router from '@ohos.router'; 17 ``` 18 19- Code reference 20 21 Import JavaScript code. 22 23 ```js 24 import utils from '../../common/utils.js'; 25 ``` 26 27 28## Objects 29 30- Application objects 31 | Name | Type | Description | 32 | -------- | -------- | -------- | 33 | $def | Object | Object that is exposed in the app.js file and obtained by `this.$app.$def`.<br/>> **NOTE**<br/>> Application objects do not support data binding. Data update should be triggered on the UI. | 34 35 Example 36 37 ```js 38 // app.js 39 export default { 40 onCreate() { 41 console.info('Application onCreate'); 42 }, 43 onDestroy() { 44 console.info('Application onDestroy'); 45 }, 46 globalData: { 47 appData: 'appData', 48 appVersion: '2.0', 49 }, 50 globalMethod() { 51 console.info('This is a global method!'); 52 this.globalData.appVersion = '3.0'; 53 } 54 }; 55 ``` 56 57 58 ```js 59 // index.js 60 export default { 61 data: { 62 appData: 'localData', 63 appVersion:'1.0', 64 }, 65 onInit() { 66 this.appData = this.$app.$def.globalData.appData; 67 this.appVersion = this.$app.$def.globalData.appVersion; 68 }, 69 invokeGlobalMethod() { 70 this.$app.$def.globalMethod(); 71 }, 72 getAppVersion() { 73 this.appVersion = this.$app.$def.globalData.appVersion; 74 } 75 } 76 ``` 77 78- Page objects 79 | Name | Type | Description | 80 | -------- | -------- | -------- | 81 | data | Object/Function | Data model of the page. If the attribute is of the function type, the return value must be of the object type. The attribute name cannot start with a dollar sign ($) or underscore (_). Do not use reserved words (for, if, show, and tid).<br/>Do not use this attribute and private or public at the same time. | 82 | $refs | Object | DOM elements or child component instances that have registered the ref attribute. For example code, see [Obtaining a DOM element](#obtaining-a-dom-element). | 83 | private | Object | Data model of the page. Private data attribute can be modified only on the current page. | 84 | public | Object | Data model of the page. Behaviors of public data attributes are the same as those of the data attribute. | 85 | props | Array/Object | Used for communication between components. This attribute can be transferred to components via <tag xxxx='value'>. A props name must be in lowercase and cannot start with a dollar sign ($) or underscore (_). Do not use reserved words (for, if, show, and tid). Currently, props does not support functions. For details, see [props](../reference/arkui-js/js-components-custom-props.md). | 86 | computed | Object | Used for pre-processing an object for reading and setting. The result is cached. The name cannot start with a dollar sign ($) or underscore (_). Do not use reserved words. For details, see [props](../reference/arkui-js/js-components-custom-props.md). | 87 88## Methods 89 90- Data methods 91 | Name | Parameter | Description | 92 | -------- | -------- | -------- | 93 | $set | key: string, value: any | Adds an attribute or modifies an existing attribute.<br/>Usage:<br/>this.$set('_key_',_value_): Add an attribute. | 94 | $delete | key: string | Deletes an attribute.<br/>Usage:<br/>this.$delete('key'): Delete an attribute. | 95 96 Example 97 98 99 ```js 100 // index.js 101 export default { 102 data: { 103 keyMap: { 104 OS: 'OpenHarmony', 105 Version: '2.0', 106 }, 107 }, 108 getAppVersion() { 109 this.$set('keyMap.Version', '3.0'); 110 console.info("keyMap.Version = " + this.keyMap.Version); // keyMap.Version = 3.0 111 112 this.$delete('keyMap'); 113 console.info("keyMap.Version = " + this.keyMap); // log print: keyMap.Version = undefined 114 } 115 } 116 ``` 117 118- Public methods 119 | Name | Parameter | Description | 120 | -------- | -------- | -------- | 121 | $element | id: string | Obtains the component with a specified ID. If no ID is specified, the root component is returned. For example code, see [Obtaining a DOM element](#obtaining-a-dom-element).<br/>Usage:<br/>```<div id='_xxx_'></div>```<br/>- this.$element('_xxx_'): Obtain the component whose ID is _xxx_.<br/>- this.$element(): Obtain the root component. | 122 | $rootElement | None | Obtains the root element.<br/>Usage: this.$rootElement().scrollTo({ duration: 500, position: 300 }), which scrolls the page by 300 px within 500 ms. | 123 | $root | N/A | Obtains the root ViewModel instance. For example code, see [Obtaining the ViewModel](#obtaining-the-viewmodel). | 124 | $parent | N/A | Obtains the parent ViewModel instance. For example code, see [Obtaining the ViewModel](#obtaining-the-viewmodel). | 125 | $child | id: string | Obtains the ViewModel instance of a custom child component with a specified ID. For example code, see [Obtaining the ViewModel](#obtaining-the-viewmodel).<br/>Usage:<br/>this.$child('xxx'): Obtain the ViewModel instance of a custom child component whose ID is _xxx_. | 126 127- Event methods 128 | Name | Parameter | Description | 129 | -------- | -------- | -------- | 130 | $watch | data: string, callback: string \| Function | Listens for attribute changes. If the value of the data attribute changes, the bound event is triggered. For details, see [props](../reference/arkui-js/js-components-custom-props.md)<br/>Usage:<br/>this.$watch('key', callback) | 131 132- Page methods 133 | Name | Parameter | Description | 134 | -------- | -------- | -------- | 135 | scrollTo<sup>6+</sup> | scrollPageParam: ScrollPageParam | Scrolls the page to the target position. You can specify the position using the ID selector or scrolling distance. | 136 137 **Table 1** ScrollPageParam<sup>6+</sup> 138 139 | Name | Type | Default Value | Description | 140 | -------- | -------- | -------- | -------- | 141 | position | number | - | Position to scroll to. | 142 | id | string | - | ID of the element to be scrolled to. | 143 | duration | number | 300 | Scrolling duration, in milliseconds. | 144 | timingFunction | string | ease | Animation curve for scrolling. Available options:<br/>[Animation Styles](../reference/arkui-js/js-components-common-animation.md) | 145 | complete | () => void | - | Callback to be invoked when the scrolling is complete. | 146 147 Example 148 149 150 ```js 151 this.$rootElement().scrollTo({position: 0}) 152 this.$rootElement().scrollTo({id: 'id', duration: 200, timingFunction: 'ease-in', complete: ()=>void}) 153 ``` 154 155 156## Obtaining a DOM Element 157 1581. Use `$refs` to obtain a DOM element. 159 160 ```html 161 <!-- index.hml --> 162 <div class="container"> 163 <image-animator class="image-player" ref="animator" images="{{images}}" duration="1s" onclick="handleClick"></image-animator> 164 </div> 165 ``` 166 167 ```js 168 // index.js 169 export default { 170 data: { 171 images: [ 172 { src: '/common/frame1.png' }, 173 { src: '/common/frame2.png' }, 174 { src: '/common/frame3.png' } 175 ] 176 }, 177 handleClick() { 178 const animator = this.$refs.animator; // Obtain the DOM element whose $refs attribute is animator. 179 const state = animator.getState(); 180 if (state === 'paused') { 181 animator.resume(); 182 } else if (state === 'stopped') { 183 animator.start(); 184 } else { 185 animator.pause(); 186 } 187 }, 188 }; 189 ``` 190 1912. Call `$element` to obtain a DOM element. 192 193 ```html 194 <!-- index.hml --> 195 <div class="container" style="width:500px;height: 700px; margin: 100px;"> 196 <image-animator class="image-player" id="animator" images="{{images}}" duration="1s" onclick="handleClick"></image-animator> 197 </div> 198 ``` 199 200 ```js 201 // index.js 202 export default { 203 data: { 204 images: [ 205 { src: '/common/frame1.png' }, 206 { src: '/common/frame2.png' }, 207 { src: '/common/frame3.png' } 208 ] 209 }, 210 handleClick() { 211 const animator = this.$element('animator'); // Obtain the DOM element whose ID is animator. 212 const state = animator.getState(); 213 if (state === 'paused') { 214 animator.resume(); 215 } else if (state === 'stopped') { 216 animator.start(); 217 } else { 218 animator.pause(); 219 } 220 }, 221 }; 222 ``` 223 224![en-us_image_0000001118642007](figures/en-us_image_0000001118642007.gif) 225 226## Obtaining the ViewModel 227 228The following shows files of the root page: 229 230```html 231<!-- root.hml --> 232<element name='parentComp' src='../../common/component/parent/parent.hml'></element> 233<div class="container"> 234 <div class="container"> 235 <text>{{text}}</text> 236 <parentComp></parentComp> 237 </div> 238</div> 239``` 240 241```js 242// root.js 243export default { 244 data: { 245 text: 'I am a root!', 246 }, 247} 248``` 249 250![en-us_image_0000001118642008](figures/en-us_image_0000001118642008.png) 251 252Customize the parent component. 253 254```html 255<!-- parent.hml --> 256<element name='childComp' src='../child/child.hml'></element> 257<div class="item" onclick="textClicked"> 258 <text class="text-style" onclick="parentClicked">parent component click</text> 259 <text class="text-style" if="{{showValue}}">hello parent component!</text> 260 <childComp id = "selfDefineChild"></childComp> 261</div> 262``` 263 264```js 265// parent.js 266export default { 267 data: { 268 showValue: false, 269 text: 'I am parent component!', 270 }, 271 parentClicked () { 272 this.showValue = !this.showValue; 273 console.info('parent component get parent text'); 274 console.info(`${this.$parent().text}`); 275 console.info("The parent component gets the child function."); 276 console.info(`${this.$child('selfDefineChild').childClicked()}`); 277 }, 278} 279``` 280 281Customize the child component. 282 283```html 284<!-- child.hml --> 285<div class="item" onclick="textClicked"> 286 <text class="text-style" onclick="childClicked">Child component clicked</text> 287 <text class="text-style" if="{{isShow}}">Hello child component</text> 288</div> 289``` 290 291```js 292// child.js 293export default { 294 data: { 295 isShow: false, 296 text: 'I am the child component!', 297 }, 298 childClicked () { 299 this.isShow = !this.isShow; 300 console.info('child component get parent text'); 301 console.info('${this.$parent().text}'); 302 console.info('child component get root text'); 303 console.info('${this.$root().text}'); 304 }, 305} 306``` 307 308![en-us_image_0000001118642009](figures/en-us_image_0000001118642009.gif)