@maccesar/titools 2.0.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/AGENTS-TEMPLATE.md +173 -0
- package/README.md +867 -0
- package/agents/ti-researcher.md +108 -0
- package/bin/titools.js +53 -0
- package/lib/commands/agents.js +126 -0
- package/lib/commands/install.js +188 -0
- package/lib/commands/uninstall.js +215 -0
- package/lib/commands/update.js +159 -0
- package/lib/config.js +119 -0
- package/lib/downloader.js +153 -0
- package/lib/installer.js +253 -0
- package/lib/platform.js +108 -0
- package/lib/symlink.js +142 -0
- package/lib/utils.js +270 -0
- package/package.json +67 -0
- package/skills/alloy-expert/SKILL.md +247 -0
- package/skills/alloy-expert/assets/ControllerAutoCleanup.js +182 -0
- package/skills/alloy-expert/references/alloy-structure.md +381 -0
- package/skills/alloy-expert/references/anti-patterns.md +133 -0
- package/skills/alloy-expert/references/code-conventions.md +469 -0
- package/skills/alloy-expert/references/contracts.md +280 -0
- package/skills/alloy-expert/references/controller-patterns.md +520 -0
- package/skills/alloy-expert/references/error-handling.md +484 -0
- package/skills/alloy-expert/references/examples.md +735 -0
- package/skills/alloy-expert/references/migration-patterns.md +298 -0
- package/skills/alloy-expert/references/patterns.md +448 -0
- package/skills/alloy-expert/references/performance-patterns.md +855 -0
- package/skills/alloy-expert/references/security-patterns.md +847 -0
- package/skills/alloy-expert/references/state-management.md +779 -0
- package/skills/alloy-expert/references/testing.md +872 -0
- package/skills/alloy-guides/SKILL.md +214 -0
- package/skills/alloy-guides/references/CLI_TASKS.md +243 -0
- package/skills/alloy-guides/references/CONCEPTS.md +191 -0
- package/skills/alloy-guides/references/CONTROLLERS.md +298 -0
- package/skills/alloy-guides/references/MODELS.md +1028 -0
- package/skills/alloy-guides/references/PURGETSS.md +56 -0
- package/skills/alloy-guides/references/VIEWS_DYNAMIC.md +242 -0
- package/skills/alloy-guides/references/VIEWS_STYLES.md +388 -0
- package/skills/alloy-guides/references/VIEWS_WITHOUT_CONTROLLERS.md +109 -0
- package/skills/alloy-guides/references/VIEWS_XML.md +558 -0
- package/skills/alloy-guides/references/WIDGETS.md +176 -0
- package/skills/alloy-howtos/SKILL.md +203 -0
- package/skills/alloy-howtos/references/best_practices.md +138 -0
- package/skills/alloy-howtos/references/cli_reference.md +253 -0
- package/skills/alloy-howtos/references/config_files.md +87 -0
- package/skills/alloy-howtos/references/custom_tags.md +147 -0
- package/skills/alloy-howtos/references/debugging_troubleshooting.md +101 -0
- package/skills/alloy-howtos/references/samples.md +167 -0
- package/skills/purgetss/SKILL.md +442 -0
- package/skills/purgetss/assets/purgetss.config.cjs +17 -0
- package/skills/purgetss/references/EXAMPLES.md +247 -0
- package/skills/purgetss/references/animation-system.md +1294 -0
- package/skills/purgetss/references/apply-directive.md +375 -0
- package/skills/purgetss/references/arbitrary-values.md +612 -0
- package/skills/purgetss/references/class-index.md +1350 -0
- package/skills/purgetss/references/cli-commands.md +948 -0
- package/skills/purgetss/references/configurable-properties.md +654 -0
- package/skills/purgetss/references/custom-rules.md +161 -0
- package/skills/purgetss/references/customization-deep-dive.md +722 -0
- package/skills/purgetss/references/dynamic-component-creation.md +489 -0
- package/skills/purgetss/references/grid-layout.md +455 -0
- package/skills/purgetss/references/icon-fonts.md +609 -0
- package/skills/purgetss/references/installation-setup.md +366 -0
- package/skills/purgetss/references/opacity-modifier.md +291 -0
- package/skills/purgetss/references/platform-modifiers.md +479 -0
- package/skills/purgetss/references/smart-mappings.md +42 -0
- package/skills/purgetss/references/titanium-resets.md +359 -0
- package/skills/purgetss/references/ui-ux-design.md +1526 -0
- package/skills/ti-guides/SKILL.md +94 -0
- package/skills/ti-guides/references/advanced-data-and-images.md +19 -0
- package/skills/ti-guides/references/alloy-cli-advanced.md +84 -0
- package/skills/ti-guides/references/alloy-data-mastery.md +29 -0
- package/skills/ti-guides/references/alloy-widgets-and-themes.md +19 -0
- package/skills/ti-guides/references/android-manifest.md +97 -0
- package/skills/ti-guides/references/app-distribution.md +258 -0
- package/skills/ti-guides/references/application-frameworks.md +377 -0
- package/skills/ti-guides/references/cli-reference.md +402 -0
- package/skills/ti-guides/references/coding-best-practices.md +102 -0
- package/skills/ti-guides/references/commonjs-advanced.md +134 -0
- package/skills/ti-guides/references/hello-world.md +100 -0
- package/skills/ti-guides/references/hyperloop-native-access.md +62 -0
- package/skills/ti-guides/references/javascript-primer.md +411 -0
- package/skills/ti-guides/references/reserved-words.md +36 -0
- package/skills/ti-guides/references/resources.md +183 -0
- package/skills/ti-guides/references/style-and-conventions.md +48 -0
- package/skills/ti-guides/references/tiapp-config.md +609 -0
- package/skills/ti-howtos/SKILL.md +174 -0
- package/skills/ti-howtos/references/android-platform-deep-dives.md +658 -0
- package/skills/ti-howtos/references/automation-fastlane-appium.md +95 -0
- package/skills/ti-howtos/references/buffer-codec-streams.md +140 -0
- package/skills/ti-howtos/references/cross-platform-development.md +348 -0
- package/skills/ti-howtos/references/debugging-profiling.md +543 -0
- package/skills/ti-howtos/references/extending-titanium.md +723 -0
- package/skills/ti-howtos/references/google-maps-v2.md +169 -0
- package/skills/ti-howtos/references/ios-map-kit.md +143 -0
- package/skills/ti-howtos/references/ios-platform-deep-dives.md +783 -0
- package/skills/ti-howtos/references/local-data-sources.md +301 -0
- package/skills/ti-howtos/references/location-and-maps.md +252 -0
- package/skills/ti-howtos/references/media-apis.md +210 -0
- package/skills/ti-howtos/references/notification-services.md +599 -0
- package/skills/ti-howtos/references/remote-data-sources.md +349 -0
- package/skills/ti-howtos/references/tutorials.md +502 -0
- package/skills/ti-howtos/references/using-modules.md +237 -0
- package/skills/ti-howtos/references/web-content-integration.md +307 -0
- package/skills/ti-howtos/references/webpack-build-pipeline.md +78 -0
- package/skills/ti-ui/SKILL.md +179 -0
- package/skills/ti-ui/references/accessibility-deep-dive.md +242 -0
- package/skills/ti-ui/references/animation-and-matrices.md +599 -0
- package/skills/ti-ui/references/application-structures.md +655 -0
- package/skills/ti-ui/references/custom-fonts-styling.md +579 -0
- package/skills/ti-ui/references/event-handling.md +393 -0
- package/skills/ti-ui/references/gestures.md +473 -0
- package/skills/ti-ui/references/icons-and-splash-screens.md +409 -0
- package/skills/ti-ui/references/layouts-and-positioning.md +462 -0
- package/skills/ti-ui/references/listviews-and-performance.md +619 -0
- package/skills/ti-ui/references/orientation.md +362 -0
- package/skills/ti-ui/references/platform-ui-android.md +635 -0
- package/skills/ti-ui/references/platform-ui-ios.md +469 -0
- package/skills/ti-ui/references/scrolling-views.md +252 -0
- package/skills/ti-ui/references/tableviews.md +568 -0
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
# Event Handling
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
|
|
5
|
+
- [Event Handling](#event-handling)
|
|
6
|
+
- [Table of Contents](#table-of-contents)
|
|
7
|
+
- [1. Event Listener Pattern](#1-event-listener-pattern)
|
|
8
|
+
- [Basic Pattern](#basic-pattern)
|
|
9
|
+
- [Controlling Event Bubbling](#controlling-event-bubbling)
|
|
10
|
+
- [Bubbling Example](#bubbling-example)
|
|
11
|
+
- [3. Firing Events](#3-firing-events)
|
|
12
|
+
- [Fire Custom Event](#fire-custom-event)
|
|
13
|
+
- [Listening to App Events](#listening-to-app-events)
|
|
14
|
+
- [Memory Warning](#memory-warning)
|
|
15
|
+
- [5. Touch Events](#5-touch-events)
|
|
16
|
+
- [Touch Event Lifecycle](#touch-event-lifecycle)
|
|
17
|
+
- [Touch Enabled](#touch-enabled)
|
|
18
|
+
- [6. Named vs Anonymous Functions](#6-named-vs-anonymous-functions)
|
|
19
|
+
- [Anonymous Function (One-time use)](#anonymous-function-one-time-use)
|
|
20
|
+
- [Named Function (Reusable)](#named-function-reusable)
|
|
21
|
+
- [7. Removing Event Listeners](#7-removing-event-listeners)
|
|
22
|
+
- [Must Match Function Signature](#must-match-function-signature)
|
|
23
|
+
- [8. Android Hardware Button Events](#8-android-hardware-button-events)
|
|
24
|
+
- [Available Events](#available-events)
|
|
25
|
+
- [Handling Back Button](#handling-back-button)
|
|
26
|
+
- [Note: Window Types](#note-window-types)
|
|
27
|
+
- [9. Android Menu](#9-android-menu)
|
|
28
|
+
- [Create Options Menu](#create-options-menu)
|
|
29
|
+
- [10. Event Listener Best Practices](#10-event-listener-best-practices)
|
|
30
|
+
- [Define Before Event May Fire](#define-before-event-may-fire)
|
|
31
|
+
- [Global Event Memory Leaks](#global-event-memory-leaks)
|
|
32
|
+
- [Remove Listeners on Window Close](#remove-listeners-on-window-close)
|
|
33
|
+
- [11. Special Considerations](#11-special-considerations)
|
|
34
|
+
- [Platform-Specific Events](#platform-specific-events)
|
|
35
|
+
- [Event Naming](#event-naming)
|
|
36
|
+
- [Custom Properties on Events](#custom-properties-on-events)
|
|
37
|
+
- [Best Practices Summary](#best-practices-summary)
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## 1. Event Listener Pattern
|
|
42
|
+
|
|
43
|
+
### Basic Pattern
|
|
44
|
+
|
|
45
|
+
```javascript
|
|
46
|
+
element.addEventListener('event_type', (e) => {
|
|
47
|
+
// code here runs when event fires
|
|
48
|
+
// 'e' is the event object
|
|
49
|
+
Ti.API.info(`The ${e.type} event happened`);
|
|
50
|
+
});
|
|
51
|
+
```
|
|
52
|
+
...
|
|
53
|
+
### Controlling Event Bubbling
|
|
54
|
+
|
|
55
|
+
```javascript
|
|
56
|
+
// Check if event bubbles
|
|
57
|
+
Ti.API.info(`Bubbles: ${e.bubbles}`);
|
|
58
|
+
|
|
59
|
+
// Stop further bubbling
|
|
60
|
+
e.cancelBubble = true;
|
|
61
|
+
|
|
62
|
+
// Prevent view from bubbling to parent
|
|
63
|
+
view.bubbleParent = false;
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Bubbling Example
|
|
67
|
+
|
|
68
|
+
```javascript
|
|
69
|
+
const win = Ti.UI.createWindow({
|
|
70
|
+
backgroundColor: 'white'
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
const container = Ti.UI.createView({
|
|
74
|
+
backgroundColor: 'yellow',
|
|
75
|
+
width: 200, height: 200
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
const button = Ti.UI.createButton({
|
|
79
|
+
title: 'Click Me',
|
|
80
|
+
width: 100, height: 50
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
button.addEventListener('click', (e) => {
|
|
84
|
+
Ti.API.info(`Button received: ${e.type}`);
|
|
85
|
+
// e.cancelBubble = true; // Would stop here
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
container.addEventListener('click', (e) => {
|
|
89
|
+
Ti.API.info(`Container received: ${e.type}`);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
win.addEventListener('click', (e) => {
|
|
93
|
+
Ti.API.info(`Window received: ${e.type}`);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
container.add(button);
|
|
97
|
+
win.open();
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**Output order**: Button → Container → Window
|
|
101
|
+
|
|
102
|
+
## 3. Firing Events
|
|
103
|
+
|
|
104
|
+
### Fire Custom Event
|
|
105
|
+
|
|
106
|
+
```javascript
|
|
107
|
+
// Fire event without data
|
|
108
|
+
button.fireEvent('customEvent');
|
|
109
|
+
|
|
110
|
+
// Fire event with data
|
|
111
|
+
button.fireEvent('customEvent', {
|
|
112
|
+
message: 'Hello',
|
|
113
|
+
count: 42
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
// Handle it
|
|
117
|
+
button.addEventListener('customEvent', (e) => {
|
|
118
|
+
Ti.API.info(`Message: ${e.message}`);
|
|
119
|
+
Ti.API.info(`Count: ${e.count}`);
|
|
120
|
+
});
|
|
121
|
+
```
|
|
122
|
+
...
|
|
123
|
+
### Listening to App Events
|
|
124
|
+
|
|
125
|
+
```javascript
|
|
126
|
+
// Listen anywhere in app
|
|
127
|
+
Ti.App.addEventListener('db_updated', (e) => {
|
|
128
|
+
Ti.API.info(`DB updated at: ${e.timestamp}`);
|
|
129
|
+
tableView.setData(getCurrentRecords());
|
|
130
|
+
});
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Memory Warning
|
|
134
|
+
|
|
135
|
+
Global event listeners persist for app lifetime, preventing garbage collection:
|
|
136
|
+
|
|
137
|
+
```javascript
|
|
138
|
+
// Good: Remove when done
|
|
139
|
+
const handler = (e) => { /* ... */ };
|
|
140
|
+
Ti.App.addEventListener('myEvent', handler);
|
|
141
|
+
// Later:
|
|
142
|
+
Ti.App.removeEventListener('myEvent', handler);
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## 5. Touch Events
|
|
146
|
+
|
|
147
|
+
### Touch Event Lifecycle
|
|
148
|
+
|
|
149
|
+
```javascript
|
|
150
|
+
view.addEventListener('touchstart', (e) => {
|
|
151
|
+
Ti.API.info(`Touch started at: ${e.x}, ${e.y}`);
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
view.addEventListener('touchmove', (e) => {
|
|
155
|
+
Ti.API.info(`Dragging to: ${e.x}, ${e.y}`);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
view.addEventListener('touchend', (e) => {
|
|
159
|
+
Ti.API.info(`Touch ended at: ${e.x}, ${e.y}`);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
view.addEventListener('touchcancel', (e) => {
|
|
163
|
+
Ti.API.info('Touch cancelled (phone call, etc.)');
|
|
164
|
+
});
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Touch Enabled
|
|
168
|
+
|
|
169
|
+
Views must have `touchEnabled: true` to react to touch events (default is true for most components):
|
|
170
|
+
|
|
171
|
+
```javascript
|
|
172
|
+
view.touchEnabled = false; // Disable touch for this view
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
If a view has `touchEnabled: false`, touch events pass to next view in stack.
|
|
176
|
+
|
|
177
|
+
## 6. Named vs Anonymous Functions
|
|
178
|
+
|
|
179
|
+
### Anonymous Function (One-time use)
|
|
180
|
+
|
|
181
|
+
```javascript
|
|
182
|
+
button.addEventListener('click', function(e) {
|
|
183
|
+
Ti.API.info('Clicked');
|
|
184
|
+
});
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Named Function (Reusable)
|
|
188
|
+
|
|
189
|
+
```javascript
|
|
190
|
+
function handleClick(e) {
|
|
191
|
+
Ti.API.info(`Clicked: ${e.type}`);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
button1.addEventListener('click', handleClick);
|
|
195
|
+
button2.addEventListener('click', handleClick);
|
|
196
|
+
|
|
197
|
+
// Can also remove:
|
|
198
|
+
button1.removeEventListener('click', handleClick);
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## 7. Removing Event Listeners
|
|
202
|
+
|
|
203
|
+
### Must Match Function Signature
|
|
204
|
+
|
|
205
|
+
```javascript
|
|
206
|
+
function myHandler(e) {
|
|
207
|
+
Ti.API.info('Handler called');
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
button.addEventListener('click', myHandler);
|
|
211
|
+
// Later:
|
|
212
|
+
button.removeEventListener('click', myHandler);
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
**Important**: Anonymous functions cannot be removed!
|
|
216
|
+
|
|
217
|
+
## 8. Android Hardware Button Events
|
|
218
|
+
|
|
219
|
+
### Available Events
|
|
220
|
+
|
|
221
|
+
| Event | Fired When |
|
|
222
|
+
| ---------------- | ---------------------- |
|
|
223
|
+
| `androidback` | Back button released |
|
|
224
|
+
| `androidhome` | Home button released |
|
|
225
|
+
| `androidsearch` | Search button released |
|
|
226
|
+
| `androidcamera` | Camera button released |
|
|
227
|
+
| `androidfocus` | Camera half-pressed |
|
|
228
|
+
| `androidvolup` | Volume-up released |
|
|
229
|
+
| `androidvoldown` | Volume-down released |
|
|
230
|
+
|
|
231
|
+
### Handling Back Button
|
|
232
|
+
|
|
233
|
+
```javascript
|
|
234
|
+
const win = Ti.UI.createWindow({ backgroundColor: 'white' });
|
|
235
|
+
|
|
236
|
+
win.addEventListener('androidback', (e) => {
|
|
237
|
+
// Prevent default behavior
|
|
238
|
+
e.bubbles = false;
|
|
239
|
+
|
|
240
|
+
// Custom back behavior
|
|
241
|
+
const dialog = Ti.UI.createAlertDialog({
|
|
242
|
+
message: 'Exit app?',
|
|
243
|
+
buttonNames: ['Yes', 'No'],
|
|
244
|
+
cancel: 1
|
|
245
|
+
});
|
|
246
|
+
dialog.addEventListener('click', (e) => {
|
|
247
|
+
if (e.index === 0) {
|
|
248
|
+
// Close app
|
|
249
|
+
const activity = Ti.Android.currentActivity;
|
|
250
|
+
activity.finish();
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
dialog.show();
|
|
254
|
+
});
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### Note: Window Types
|
|
258
|
+
|
|
259
|
+
Since 3.2.0, all windows are heavyweight by default and can receive hardware button events.
|
|
260
|
+
|
|
261
|
+
## 9. Android Menu
|
|
262
|
+
|
|
263
|
+
### Create Options Menu
|
|
264
|
+
|
|
265
|
+
```javascript
|
|
266
|
+
const activity = Ti.Android.currentActivity;
|
|
267
|
+
|
|
268
|
+
activity.onCreateOptionsMenu = (e) => {
|
|
269
|
+
const menu = e.menu;
|
|
270
|
+
|
|
271
|
+
// Add menu items
|
|
272
|
+
const menuItem = menu.add({
|
|
273
|
+
title: 'Refresh',
|
|
274
|
+
icon: Ti.App.Android.R.drawable.ic_menu_refresh,
|
|
275
|
+
showAsAction: Ti.Android.SHOW_AS_ACTION_IF_ROOM
|
|
276
|
+
});
|
|
277
|
+
menuItem.addEventListener('click', () => {
|
|
278
|
+
refreshData();
|
|
279
|
+
});
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
activity.onPrepareOptionsMenu = (e) => {
|
|
283
|
+
// Update menu before showing
|
|
284
|
+
const menu = e.menu;
|
|
285
|
+
// Modify items based on state
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
activity.onOptionsItemSelected = (e) => {
|
|
289
|
+
// Handle menu item selection
|
|
290
|
+
if (e.itemId === SOME_ID) {
|
|
291
|
+
return true; // Event handled
|
|
292
|
+
}
|
|
293
|
+
return false; // Event not handled
|
|
294
|
+
};
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
## 10. Event Listener Best Practices
|
|
298
|
+
|
|
299
|
+
### Define Before Event May Fire
|
|
300
|
+
|
|
301
|
+
```javascript
|
|
302
|
+
// GOOD: Define before opening
|
|
303
|
+
win.addEventListener('open', () => {
|
|
304
|
+
Ti.API.info('Window opened');
|
|
305
|
+
});
|
|
306
|
+
win.open();
|
|
307
|
+
|
|
308
|
+
// BAD: Might miss event
|
|
309
|
+
win.open();
|
|
310
|
+
win.addEventListener('open', function(e) {
|
|
311
|
+
// May not fire
|
|
312
|
+
});
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
### Global Event Memory Leaks
|
|
316
|
+
|
|
317
|
+
```javascript
|
|
318
|
+
// BAD: Global listener with local reference
|
|
319
|
+
function init() {
|
|
320
|
+
const localData = 'some data';
|
|
321
|
+
|
|
322
|
+
Ti.App.addEventListener('update', () => {
|
|
323
|
+
// 'localData' stays in memory forever
|
|
324
|
+
Ti.API.info(localData);
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// GOOD: Remove when done
|
|
329
|
+
function init() {
|
|
330
|
+
const handler = () => {
|
|
331
|
+
Ti.API.info('data');
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
Ti.App.addEventListener('update', handler);
|
|
335
|
+
|
|
336
|
+
// Later, when done:
|
|
337
|
+
// Ti.App.removeEventListener('update', handler);
|
|
338
|
+
}
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
### Remove Listeners on Window Close
|
|
342
|
+
|
|
343
|
+
```javascript
|
|
344
|
+
const win = Ti.UI.createWindow();
|
|
345
|
+
const handler = (e) => { /* ... */ };
|
|
346
|
+
|
|
347
|
+
someComponent.addEventListener('event', handler);
|
|
348
|
+
|
|
349
|
+
win.addEventListener('close', () => {
|
|
350
|
+
someComponent.removeEventListener('event', handler);
|
|
351
|
+
});
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
## 11. Special Considerations
|
|
355
|
+
|
|
356
|
+
### Platform-Specific Events
|
|
357
|
+
|
|
358
|
+
Some events only work on certain platforms:
|
|
359
|
+
- `pinch` - iOS only
|
|
360
|
+
- `globalPoint` property - iOS only
|
|
361
|
+
- Hardware buttons - Android only
|
|
362
|
+
|
|
363
|
+
### Event Naming
|
|
364
|
+
|
|
365
|
+
**WARNING**: Do NOT use spaces in custom event names (causes issues with libraries like Backbone.js):
|
|
366
|
+
|
|
367
|
+
```javascript
|
|
368
|
+
// BAD
|
|
369
|
+
Ti.App.fireEvent('my event');
|
|
370
|
+
|
|
371
|
+
// GOOD
|
|
372
|
+
Ti.App.fireEvent('my_event');
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
### Custom Properties on Events
|
|
376
|
+
|
|
377
|
+
```javascript
|
|
378
|
+
button.whichObj = 'button';
|
|
379
|
+
|
|
380
|
+
button.addEventListener('click', function(e) {
|
|
381
|
+
Ti.API.info('Source: ' + e.source.whichObj);
|
|
382
|
+
});
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
## Best Practices Summary
|
|
386
|
+
|
|
387
|
+
1. **Use app-level events** for cross-context communication
|
|
388
|
+
2. **Remove global listeners** when no longer needed to prevent memory leaks
|
|
389
|
+
3. **Use named functions** when you might need to remove listeners later
|
|
390
|
+
4. **Understand bubbling** to control event propagation
|
|
391
|
+
5. **Define listeners early** - before events are likely to fire
|
|
392
|
+
6. **Handle Android back button** for custom navigation
|
|
393
|
+
7. **Test touch events** on device - simulator may not support all gestures
|