@maccesar/titools 5.3.0 → 5.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTRIBUTING.md +1 -1
- package/README.md +31 -60
- package/agents/ti-pro.md +3 -1
- package/commands/ti-audit.md +6 -4
- package/docs/examples.md +9 -0
- package/docs/knowledge-index.md +2 -1
- package/lib/config.js +1 -0
- package/package.json +1 -1
- package/skills/alloy-guides/SKILL.md +18 -179
- package/skills/alloy-guides/references/CLI_TASKS.md +17 -216
- package/skills/alloy-guides/references/CONCEPTS.md +27 -162
- package/skills/alloy-guides/references/CONTROLLERS.md +38 -236
- package/skills/alloy-guides/references/MODELS.md +47 -723
- package/skills/alloy-guides/references/MODELS_ADVANCED.md +21 -482
- package/skills/alloy-guides/references/VIEWS_DYNAMIC.md +12 -222
- package/skills/alloy-guides/references/VIEWS_STYLES.md +39 -358
- package/skills/alloy-guides/references/VIEWS_XML.md +36 -552
- package/skills/alloy-guides/references/WIDGETS.md +49 -127
- package/skills/alloy-howtos/SKILL.md +14 -169
- package/skills/alloy-howtos/references/best_practices.md +9 -113
- package/skills/alloy-howtos/references/cli_reference.md +18 -223
- package/skills/alloy-howtos/references/config_files.md +50 -133
- package/skills/alloy-howtos/references/debugging_troubleshooting.md +19 -63
- package/skills/alloy-howtos/references/samples.md +21 -138
- package/skills/ti-api/SKILL.md +10 -2
- package/skills/ti-api/references/api-android.md +36 -2
- package/skills/ti-api/references/api-app-platform.md +39 -3
- package/skills/ti-api/references/api-core.md +50 -18
- package/skills/ti-api/references/api-data-network.md +49 -35
- package/skills/ti-api/references/api-media.md +45 -27
- package/skills/ti-api/references/api-services.md +39 -9
- package/skills/ti-api/references/api-ui-android.md +33 -13
- package/skills/ti-api/references/api-ui-extras.md +41 -15
- package/skills/ti-api/references/api-ui-ios-animator.md +42 -26
- package/skills/ti-api/references/api-ui-ios.md +74 -2
- package/skills/ti-api/references/api-ui-lists.md +32 -16
- package/skills/ti-api/references/api-ui-text-input.md +34 -17
- package/skills/ti-api/references/api-ui-views.md +27 -1
- package/skills/ti-api/references/api-ui-windows-navigation.md +32 -18
- package/skills/ti-api/references/api-xml-global.md +66 -16
- package/skills/ti-create-release/SKILL.md +98 -0
- package/skills/ti-create-release/references/module-discovery.md +69 -0
- package/skills/ti-expert/references/adaptive-layouts.md +1 -1
- package/skills/ti-guides/SKILL.md +37 -76
- package/skills/ti-guides/references/advanced-data-and-images.md +122 -126
- package/skills/ti-guides/references/android-manifest.md +24 -83
- package/skills/ti-guides/references/app-distribution.md +31 -377
- package/skills/ti-guides/references/application-frameworks.md +127 -335
- package/skills/ti-guides/references/cli-reference.md +184 -633
- package/skills/ti-guides/references/commonjs-advanced.md +81 -231
- package/skills/ti-guides/references/compatibility-matrix.md +36 -75
- package/skills/ti-guides/references/hello-world.md +95 -70
- package/skills/ti-guides/references/hyperloop-native-access.md +52 -448
- package/skills/ti-guides/references/resources.md +174 -142
- package/skills/ti-guides/references/sdk-release-notes.md +28 -71
- package/skills/ti-guides/references/tiapp-config.md +222 -598
- package/skills/ti-howtos/SKILL.md +23 -123
- package/skills/ti-howtos/references/cross-platform-development.md +119 -324
- package/skills/ti-howtos/references/debugging-profiling.md +77 -445
- package/skills/ti-howtos/references/extending-titanium.md +199 -673
- package/skills/ti-howtos/references/local-data-sources.md +87 -300
- package/skills/ti-howtos/references/location-and-maps.md +86 -213
- package/skills/ti-howtos/references/media-apis.md +103 -223
- package/skills/ti-howtos/references/notification-services.md +86 -506
- package/skills/ti-howtos/references/remote-data-sources.md +97 -316
- package/skills/ti-howtos/references/using-modules.md +77 -133
- package/skills/ti-ui/SKILL.md +28 -143
- package/skills/ti-ui/references/icons-and-splash-screens.md +74 -403
- package/skills/ti-ui/references/layouts-and-positioning.md +175 -402
- package/skills/ti-ui/references/listviews-and-performance.md +100 -703
- package/skills/ti-ui/references/platform-conventions.md +180 -0
- package/skills/ti-ui/references/user-interface.md +43 -0
- package/skills/alloy-guides/references/VIEWS_WITHOUT_CONTROLLERS.md +0 -102
- package/skills/alloy-howtos/references/custom_tags.md +0 -148
- package/skills/ti-guides/references/coding-best-practices.md +0 -149
- package/skills/ti-guides/references/javascript-primer.md +0 -414
- package/skills/ti-guides/references/reserved-words.md +0 -36
- package/skills/ti-guides/references/style-and-conventions.md +0 -103
- package/skills/ti-howtos/references/android-platform-deep-dives.md +0 -624
- package/skills/ti-howtos/references/automation-fastlane-appium.md +0 -96
- package/skills/ti-howtos/references/buffer-codec-streams.md +0 -162
- package/skills/ti-howtos/references/google-maps-v2.md +0 -172
- package/skills/ti-howtos/references/ios-map-kit.md +0 -149
- package/skills/ti-howtos/references/ios-platform-deep-dives.md +0 -611
- package/skills/ti-howtos/references/tutorials.md +0 -565
- package/skills/ti-howtos/references/web-content-integration.md +0 -287
- package/skills/ti-howtos/references/webpack-build-pipeline.md +0 -124
- package/skills/ti-ui/references/accessibility-deep-dive.md +0 -288
- package/skills/ti-ui/references/animation-and-matrices.md +0 -569
- package/skills/ti-ui/references/application-structures.md +0 -626
- package/skills/ti-ui/references/custom-fonts-styling.md +0 -549
- package/skills/ti-ui/references/event-handling.md +0 -401
- package/skills/ti-ui/references/gestures.md +0 -448
- package/skills/ti-ui/references/orientation.md +0 -374
- package/skills/ti-ui/references/platform-ui-android.md +0 -727
- package/skills/ti-ui/references/platform-ui-ios.md +0 -576
- package/skills/ti-ui/references/scrolling-views.md +0 -288
- package/skills/ti-ui/references/tableviews.md +0 -542
|
@@ -1,401 +0,0 @@
|
|
|
1
|
-
# Event handling
|
|
2
|
-
|
|
3
|
-
<!-- TOC-START -->
|
|
4
|
-
## Contents
|
|
5
|
-
|
|
6
|
-
- [1. Event listener pattern](#1-event-listener-pattern)
|
|
7
|
-
- [3. Firing events](#3-firing-events)
|
|
8
|
-
- [5. Touch events](#5-touch-events)
|
|
9
|
-
- [6. Named vs anonymous functions](#6-named-vs-anonymous-functions)
|
|
10
|
-
- [7. Removing event listeners](#7-removing-event-listeners)
|
|
11
|
-
- [8. Android hardware button events](#8-android-hardware-button-events)
|
|
12
|
-
- [9. Android menu](#9-android-menu)
|
|
13
|
-
- [10. Event listener best practices](#10-event-listener-best-practices)
|
|
14
|
-
- [11. Special considerations](#11-special-considerations)
|
|
15
|
-
- [Best practices summary](#best-practices-summary)
|
|
16
|
-
|
|
17
|
-
<!-- TOC-END -->
|
|
18
|
-
|
|
19
|
-
## 1. Event listener pattern
|
|
20
|
-
|
|
21
|
-
### Basic pattern
|
|
22
|
-
|
|
23
|
-
```javascript
|
|
24
|
-
element.addEventListener('event_type', (e) => {
|
|
25
|
-
// code here runs when event fires
|
|
26
|
-
// 'e' is the event object
|
|
27
|
-
Ti.API.info(`The ${e.type} event happened`);
|
|
28
|
-
});
|
|
29
|
-
```
|
|
30
|
-
...
|
|
31
|
-
### Events that bubble
|
|
32
|
-
|
|
33
|
-
All user input events defined by `Ti.UI.View` bubble up the view hierarchy: `click`, `dblclick`, `doubletap`, `longclick`, `longpress`, `pinch`, `singletap`, `swipe`, `touchcancel`, `touchend`, `touchmove`, `touchstart`, `twofingertap`. The only `Ti.UI.View` event that does not bubble is `postlayout`.
|
|
34
|
-
|
|
35
|
-
Event synonyms: `singletap` is a synonym for `click`, and `doubletap` is a synonym for `dblclick`.
|
|
36
|
-
|
|
37
|
-
Events that represent view-specific state, such as `focus`, `scroll`, and `postlayout`, do not bubble. Only user input events bubble.
|
|
38
|
-
|
|
39
|
-
### Bubbling boundaries
|
|
40
|
-
|
|
41
|
-
Bubbling stops at these container boundaries: `Window`, `NavigationWindow`, `SplitWindow`, `Tab`, and `TabGroup`.
|
|
42
|
-
|
|
43
|
-
`TableViewSection` is a logical (non-view) container that still participates in bubbling. Events from rows bubble through the section to the `TableView`.
|
|
44
|
-
|
|
45
|
-
### Native event handling precedence
|
|
46
|
-
|
|
47
|
-
Event bubbling happens after native event handling. UI effects like highlighting already happened before handlers run.
|
|
48
|
-
|
|
49
|
-
### Controlling event bubbling
|
|
50
|
-
|
|
51
|
-
```javascript
|
|
52
|
-
// Check if event bubbles
|
|
53
|
-
Ti.API.info(`Bubbles: ${e.bubbles}`);
|
|
54
|
-
|
|
55
|
-
// Stop further bubbling - cancelBubble is always false when an event handler is invoked
|
|
56
|
-
e.cancelBubble = true;
|
|
57
|
-
|
|
58
|
-
// Prevent view from bubbling to parent
|
|
59
|
-
view.bubbleParent = false;
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
Note: Each event type is handled separately. If the user lifting their finger triggers `touchend`, `singletap`, and `click`, setting `cancelBubble` on one does not affect the others.
|
|
63
|
-
|
|
64
|
-
### Bubbling example
|
|
65
|
-
|
|
66
|
-
```javascript
|
|
67
|
-
const win = Ti.UI.createWindow({
|
|
68
|
-
backgroundColor: 'white'
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
const container = Ti.UI.createView({
|
|
72
|
-
backgroundColor: 'yellow',
|
|
73
|
-
width: 200, height: 200
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
const button = Ti.UI.createButton({
|
|
77
|
-
title: 'Click Me',
|
|
78
|
-
width: 100, height: 50
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
button.addEventListener('click', (e) => {
|
|
82
|
-
Ti.API.info(`Button received: ${e.type}`);
|
|
83
|
-
// e.cancelBubble = true; // Would stop here
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
container.addEventListener('click', (e) => {
|
|
87
|
-
Ti.API.info(`Container received: ${e.type}`);
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
win.addEventListener('click', (e) => {
|
|
91
|
-
Ti.API.info(`Window received: ${e.type}`);
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
container.add(button);
|
|
95
|
-
win.open();
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
Output order: Button -> Container -> Window
|
|
99
|
-
|
|
100
|
-
## 3. Firing events
|
|
101
|
-
|
|
102
|
-
### Fire custom event
|
|
103
|
-
|
|
104
|
-
```javascript
|
|
105
|
-
// Fire event without data
|
|
106
|
-
button.fireEvent('customEvent');
|
|
107
|
-
|
|
108
|
-
// Fire event with data
|
|
109
|
-
button.fireEvent('customEvent', {
|
|
110
|
-
message: 'Hello',
|
|
111
|
-
count: 42
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
// Handle it
|
|
115
|
-
button.addEventListener('customEvent', (e) => {
|
|
116
|
-
Ti.API.info(`Message: ${e.message}`);
|
|
117
|
-
Ti.API.info(`Count: ${e.count}`);
|
|
118
|
-
});
|
|
119
|
-
```
|
|
120
|
-
...
|
|
121
|
-
### Listening to app events
|
|
122
|
-
|
|
123
|
-
```javascript
|
|
124
|
-
// Listen anywhere in app
|
|
125
|
-
Ti.App.addEventListener('db_updated', (e) => {
|
|
126
|
-
Ti.API.info(`DB updated at: ${e.timestamp}`);
|
|
127
|
-
tableView.setData(getCurrentRecords());
|
|
128
|
-
});
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
### Memory warning
|
|
132
|
-
|
|
133
|
-
Global event listeners persist for the app lifetime and prevent garbage collection:
|
|
134
|
-
|
|
135
|
-
```javascript
|
|
136
|
-
// Good: Remove when done
|
|
137
|
-
const handler = (e) => { /* ... */ };
|
|
138
|
-
Ti.App.addEventListener('myEvent', handler);
|
|
139
|
-
// Later:
|
|
140
|
-
Ti.App.removeEventListener('myEvent', handler);
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
## 5. Touch events
|
|
144
|
-
|
|
145
|
-
### Touch event lifecycle
|
|
146
|
-
|
|
147
|
-
```javascript
|
|
148
|
-
view.addEventListener('touchstart', (e) => {
|
|
149
|
-
Ti.API.info(`Touch started at: ${e.x}, ${e.y}`);
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
view.addEventListener('touchmove', (e) => {
|
|
153
|
-
Ti.API.info(`Dragging to: ${e.x}, ${e.y}`);
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
view.addEventListener('touchend', (e) => {
|
|
157
|
-
Ti.API.info(`Touch ended at: ${e.x}, ${e.y}`);
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
view.addEventListener('touchcancel', (e) => {
|
|
161
|
-
Ti.API.info('Touch cancelled (phone call, etc.)');
|
|
162
|
-
});
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
### Touch enabled
|
|
166
|
-
|
|
167
|
-
Views must have `touchEnabled: true` to react to touch events. It is true by default for most components.
|
|
168
|
-
|
|
169
|
-
```javascript
|
|
170
|
-
view.touchEnabled = false; // Disable touch for this view
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
If a view has `touchEnabled: false`, touch events pass to the next view in the stack.
|
|
174
|
-
|
|
175
|
-
## 6. Named vs anonymous functions
|
|
176
|
-
|
|
177
|
-
### Anonymous function (one-time use)
|
|
178
|
-
|
|
179
|
-
```javascript
|
|
180
|
-
button.addEventListener('click', function(e) {
|
|
181
|
-
Ti.API.info('Clicked');
|
|
182
|
-
});
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
### Named function (reusable)
|
|
186
|
-
|
|
187
|
-
```javascript
|
|
188
|
-
function handleClick(e) {
|
|
189
|
-
Ti.API.info(`Clicked: ${e.type}`);
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
button1.addEventListener('click', handleClick);
|
|
193
|
-
button2.addEventListener('click', handleClick);
|
|
194
|
-
|
|
195
|
-
// Can also remove:
|
|
196
|
-
button1.removeEventListener('click', handleClick);
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
## 7. Removing event listeners
|
|
200
|
-
|
|
201
|
-
### Must match function reference
|
|
202
|
-
|
|
203
|
-
```javascript
|
|
204
|
-
function myHandler(e) {
|
|
205
|
-
Ti.API.info('Handler called');
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
button.addEventListener('click', myHandler);
|
|
209
|
-
// Later:
|
|
210
|
-
button.removeEventListener('click', myHandler);
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
Important: Anonymous functions cannot be removed.
|
|
214
|
-
|
|
215
|
-
## 8. Android hardware button events
|
|
216
|
-
|
|
217
|
-
### Available events
|
|
218
|
-
|
|
219
|
-
| Event | Fired when |
|
|
220
|
-
| ---------------- | ---------------------- |
|
|
221
|
-
| `androidback` | Back button released |
|
|
222
|
-
| `androidhome` | Home button released |
|
|
223
|
-
| `androidsearch` | Search button released |
|
|
224
|
-
| `androidcamera` | Camera button released |
|
|
225
|
-
| `androidfocus` | Camera half-pressed |
|
|
226
|
-
| `androidvolup` | Volume-up released |
|
|
227
|
-
| `androidvoldown` | Volume-down released |
|
|
228
|
-
|
|
229
|
-
### Handling back button
|
|
230
|
-
|
|
231
|
-
```javascript
|
|
232
|
-
const win = Ti.UI.createWindow({ backgroundColor: 'white' });
|
|
233
|
-
|
|
234
|
-
win.addEventListener('androidback', (e) => {
|
|
235
|
-
// Prevent default behavior
|
|
236
|
-
e.bubbles = false;
|
|
237
|
-
|
|
238
|
-
// Custom back behavior
|
|
239
|
-
const dialog = Ti.UI.createAlertDialog({
|
|
240
|
-
message: 'Exit app?',
|
|
241
|
-
buttonNames: ['Yes', 'No'],
|
|
242
|
-
cancel: 1
|
|
243
|
-
});
|
|
244
|
-
dialog.addEventListener('click', (e) => {
|
|
245
|
-
if (e.index === 0) {
|
|
246
|
-
// Close app
|
|
247
|
-
const activity = Ti.Android.currentActivity;
|
|
248
|
-
activity.finish();
|
|
249
|
-
}
|
|
250
|
-
});
|
|
251
|
-
dialog.show();
|
|
252
|
-
});
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
### Note: Window types
|
|
256
|
-
|
|
257
|
-
Since 3.2.0, all windows are heavyweight by default and you cannot control the type of window created. All windows can receive hardware button events.
|
|
258
|
-
|
|
259
|
-
## 9. Android menu
|
|
260
|
-
|
|
261
|
-
### Create options menu
|
|
262
|
-
|
|
263
|
-
```javascript
|
|
264
|
-
const activity = Ti.Android.currentActivity;
|
|
265
|
-
|
|
266
|
-
activity.onCreateOptionsMenu = (e) => {
|
|
267
|
-
const menu = e.menu;
|
|
268
|
-
|
|
269
|
-
// Add menu items
|
|
270
|
-
const menuItem = menu.add({
|
|
271
|
-
title: 'Refresh',
|
|
272
|
-
icon: Ti.App.Android.R.drawable.ic_menu_refresh,
|
|
273
|
-
showAsAction: Ti.Android.SHOW_AS_ACTION_IF_ROOM
|
|
274
|
-
});
|
|
275
|
-
menuItem.addEventListener('click', () => {
|
|
276
|
-
refreshData();
|
|
277
|
-
});
|
|
278
|
-
};
|
|
279
|
-
|
|
280
|
-
activity.onPrepareOptionsMenu = (e) => {
|
|
281
|
-
// Update menu before showing
|
|
282
|
-
const menu = e.menu;
|
|
283
|
-
// Modify items based on state
|
|
284
|
-
};
|
|
285
|
-
|
|
286
|
-
activity.onOptionsItemSelected = (e) => {
|
|
287
|
-
// Handle menu item selection
|
|
288
|
-
if (e.itemId === SOME_ID) {
|
|
289
|
-
return true; // Event handled
|
|
290
|
-
}
|
|
291
|
-
return false; // Event not handled
|
|
292
|
-
};
|
|
293
|
-
```
|
|
294
|
-
|
|
295
|
-
## 10. Event listener best practices
|
|
296
|
-
|
|
297
|
-
### Define before the event may fire
|
|
298
|
-
|
|
299
|
-
```javascript
|
|
300
|
-
// GOOD: Define before opening
|
|
301
|
-
win.addEventListener('open', () => {
|
|
302
|
-
Ti.API.info('Window opened');
|
|
303
|
-
});
|
|
304
|
-
win.open();
|
|
305
|
-
|
|
306
|
-
// BAD: Might miss event
|
|
307
|
-
win.open();
|
|
308
|
-
win.addEventListener('open', function(e) {
|
|
309
|
-
// May not fire
|
|
310
|
-
});
|
|
311
|
-
```
|
|
312
|
-
|
|
313
|
-
### Global event memory leaks
|
|
314
|
-
|
|
315
|
-
```javascript
|
|
316
|
-
// BAD: Global listener with local reference
|
|
317
|
-
function init() {
|
|
318
|
-
const localData = 'some data';
|
|
319
|
-
|
|
320
|
-
Ti.App.addEventListener('update', () => {
|
|
321
|
-
// 'localData' stays in memory forever
|
|
322
|
-
Ti.API.info(localData);
|
|
323
|
-
});
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
// GOOD: Remove when done
|
|
327
|
-
function init() {
|
|
328
|
-
const handler = () => {
|
|
329
|
-
Ti.API.info('data');
|
|
330
|
-
};
|
|
331
|
-
|
|
332
|
-
Ti.App.addEventListener('update', handler);
|
|
333
|
-
|
|
334
|
-
// Later, when done:
|
|
335
|
-
// Ti.App.removeEventListener('update', handler);
|
|
336
|
-
}
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
### Remove listeners on window close
|
|
340
|
-
|
|
341
|
-
```javascript
|
|
342
|
-
const win = Ti.UI.createWindow();
|
|
343
|
-
const handler = (e) => { /* ... */ };
|
|
344
|
-
|
|
345
|
-
someComponent.addEventListener('event', handler);
|
|
346
|
-
|
|
347
|
-
win.addEventListener('close', () => {
|
|
348
|
-
someComponent.removeEventListener('event', handler);
|
|
349
|
-
});
|
|
350
|
-
```
|
|
351
|
-
|
|
352
|
-
## 11. Special considerations
|
|
353
|
-
|
|
354
|
-
### Platform-specific events
|
|
355
|
-
|
|
356
|
-
Some events only work on certain platforms:
|
|
357
|
-
- `pinch` - iOS only
|
|
358
|
-
- `globalPoint` property - iOS only
|
|
359
|
-
- Hardware buttons - Android only
|
|
360
|
-
|
|
361
|
-
### Shake event
|
|
362
|
-
|
|
363
|
-
The `Ti.Gesture` module enables listening for the `shake` event, which fires when the device detects a shake motion:
|
|
364
|
-
|
|
365
|
-
```javascript
|
|
366
|
-
Ti.Gesture.addEventListener('shake', (e) => {
|
|
367
|
-
Ti.API.info(`Device shaken at timestamp: ${e.timestamp}`);
|
|
368
|
-
});
|
|
369
|
-
```
|
|
370
|
-
|
|
371
|
-
### Event naming
|
|
372
|
-
|
|
373
|
-
Warning: Do not use spaces in custom event names. It can break libraries like Backbone.js.
|
|
374
|
-
|
|
375
|
-
```javascript
|
|
376
|
-
// BAD
|
|
377
|
-
Ti.App.fireEvent('my event');
|
|
378
|
-
|
|
379
|
-
// GOOD
|
|
380
|
-
Ti.App.fireEvent('my_event');
|
|
381
|
-
```
|
|
382
|
-
|
|
383
|
-
### Custom properties on events
|
|
384
|
-
|
|
385
|
-
```javascript
|
|
386
|
-
button.whichObj = 'button';
|
|
387
|
-
|
|
388
|
-
button.addEventListener('click', function(e) {
|
|
389
|
-
Ti.API.info('Source: ' + e.source.whichObj);
|
|
390
|
-
});
|
|
391
|
-
```
|
|
392
|
-
|
|
393
|
-
## Best practices summary
|
|
394
|
-
|
|
395
|
-
1. Use app-level events for cross-context communication.
|
|
396
|
-
2. Remove global listeners when no longer needed.
|
|
397
|
-
3. Use named functions when you might need to remove listeners later.
|
|
398
|
-
4. Understand bubbling to control event propagation.
|
|
399
|
-
5. Define listeners early, before events are likely to fire.
|
|
400
|
-
6. Handle Android back button for custom navigation.
|
|
401
|
-
7. Test touch events on device. Simulator may not support all gestures.
|