0
# Event Callbacks
1
2
Comprehensive callback system for hooking into tour lifecycle events and user interactions. Callbacks enable custom behavior, validation, and integration with application logic.
3
4
## Capabilities
5
6
### Tour Lifecycle Callbacks
7
8
#### Before Change Callback
9
10
Called before each step change, can prevent the step change by returning false.
11
12
```typescript { .api }
13
/**
14
* Register callback for before step change
15
* @param providedCallback - Function called before step changes
16
* @returns IntroJs instance for chaining
17
*/
18
onbeforechange(providedCallback: introBeforeChangeCallback): IntroJs;
19
20
type introBeforeChangeCallback = (
21
this: IntroJs,
22
targetElement: HTMLElement,
23
currentStep: number,
24
direction: "backward" | "forward"
25
) => Promise<boolean> | boolean;
26
```
27
28
#### Change Callback
29
30
Called when a step change occurs.
31
32
```typescript { .api }
33
/**
34
* Register callback for step change
35
* @param providedCallback - Function called when step changes
36
* @returns IntroJs instance for chaining
37
*/
38
onchange(providedCallback: introChangeCallback): IntroJs;
39
40
type introChangeCallback = (
41
this: IntroJs,
42
targetElement: HTMLElement
43
) => void | Promise<void>;
44
```
45
46
#### After Change Callback
47
48
Called after a step change is complete, including any animations and positioning updates.
49
50
```typescript { .api }
51
/**
52
* Register callback for after step change
53
* @param providedCallback - Function called after step change completes
54
* @returns IntroJs instance for chaining
55
*/
56
onafterchange(providedCallback: introAfterChangeCallback): IntroJs;
57
58
type introAfterChangeCallback = (
59
this: IntroJs,
60
targetElement: HTMLElement
61
) => void | Promise<void>;
62
```
63
64
#### Start Callback
65
66
Called when the tour starts.
67
68
```typescript { .api }
69
/**
70
* Register callback for tour start
71
* @param providedCallback - Function called when tour starts
72
* @returns IntroJs instance for chaining
73
*/
74
onstart(providedCallback: introStartCallback): IntroJs;
75
76
type introStartCallback = (
77
this: IntroJs,
78
targetElement: HTMLElement
79
) => void | Promise<void>;
80
```
81
82
#### Complete Callback
83
84
Called when the tour completes (reaches the end or is explicitly completed).
85
86
```typescript { .api }
87
/**
88
* Register callback for tour completion
89
* @param providedCallback - Function called when tour completes
90
* @returns IntroJs instance for chaining
91
*/
92
oncomplete(providedCallback: introCompleteCallback): IntroJs;
93
94
type introCompleteCallback = (
95
this: IntroJs,
96
currentStep: number,
97
reason: "skip" | "end" | "done"
98
) => void | Promise<void>;
99
```
100
101
#### Exit Callback
102
103
Called when the tour exits.
104
105
```typescript { .api }
106
/**
107
* Register callback for tour exit
108
* @param providedCallback - Function called when tour exits
109
* @returns IntroJs instance for chaining
110
*/
111
onexit(providedCallback: introExitCallback): IntroJs;
112
113
type introExitCallback = (this: IntroJs) => void | Promise<void>;
114
```
115
116
#### Skip Callback
117
118
Called when the user skips the tour.
119
120
```typescript { .api }
121
/**
122
* Register callback for tour skip
123
* @param providedCallback - Function called when tour is skipped
124
* @returns IntroJs instance for chaining
125
*/
126
onskip(providedCallback: introSkipCallback): IntroJs;
127
128
type introSkipCallback = (
129
this: IntroJs,
130
currentStep: number
131
) => void | Promise<void>;
132
```
133
134
#### Before Exit Callback
135
136
Called before the tour exits, can prevent exit by returning false.
137
138
```typescript { .api }
139
/**
140
* Register callback for before tour exit
141
* @param providedCallback - Function called before tour exits
142
* @returns IntroJs instance for chaining
143
*/
144
onbeforeexit(providedCallback: introBeforeExitCallback): IntroJs;
145
146
type introBeforeExitCallback = (
147
this: IntroJs,
148
targetElement: HTMLElement
149
) => boolean | Promise<boolean>;
150
```
151
152
**Error Handling:**
153
154
All callback registration methods throw an Error if the provided callback is not a function.
155
156
**Usage Examples:**
157
158
```typescript
159
import introJs from "intro.js";
160
161
// Basic lifecycle callbacks
162
const intro = introJs()
163
.onstart(function(targetElement) {
164
console.log("Tour started on element:", targetElement);
165
// Track tour start in analytics
166
analytics.track("tour_started");
167
})
168
.onbeforechange(function(targetElement, currentStep, direction) {
169
console.log(`Moving ${direction} from step ${currentStep}`);
170
171
// Validate before proceeding to next step
172
if (direction === "forward" && currentStep === 2) {
173
const isValid = validateUserInput();
174
if (!isValid) {
175
alert("Please complete the form before continuing");
176
return false; // Prevent step change
177
}
178
}
179
return true;
180
})
181
.onchange(function(targetElement) {
182
console.log("Changed to element:", targetElement);
183
// Update UI or scroll to ensure element is visible
184
targetElement.scrollIntoView({ behavior: "smooth" });
185
})
186
.onafterchange(function(targetElement) {
187
// Step change animation is complete, safe to perform DOM operations
188
console.log("Step change completed for:", targetElement);
189
// Trigger any post-transition effects
190
highlightImportantFeatures(targetElement);
191
})
192
.oncomplete(function(currentStep, reason) {
193
console.log(`Tour completed at step ${currentStep} with reason: ${reason}`);
194
// Track completion in analytics
195
analytics.track("tour_completed", {
196
steps_completed: currentStep,
197
completion_reason: reason
198
});
199
})
200
.onexit(function() {
201
console.log("Tour exited");
202
// Clean up any temporary state
203
cleanupTourState();
204
})
205
.onskip(function(currentStep) {
206
console.log(`Tour skipped at step ${currentStep}`);
207
// Track skip event
208
analytics.track("tour_skipped", { step: currentStep });
209
})
210
.onbeforeexit(function(targetElement) {
211
// Confirm before exiting
212
return confirm("Are you sure you want to exit the tour?");
213
});
214
```
215
216
### Hint System Callbacks
217
218
#### Hints Added Callback
219
220
Called when hints are added to the page.
221
222
```typescript { .api }
223
/**
224
* Register callback for when hints are added
225
* @param providedCallback - Function called when hints are added
226
* @returns IntroJs instance for chaining
227
*/
228
onhintsadded(providedCallback: hintsAddedCallback): IntroJs;
229
230
type hintsAddedCallback = (this: IntroJs) => void | Promise<void>;
231
```
232
233
#### Hint Click Callback
234
235
Called when a hint is clicked.
236
237
```typescript { .api }
238
/**
239
* Register callback for hint click
240
* @param providedCallback - Function called when hint is clicked
241
* @returns IntroJs instance for chaining
242
*/
243
onhintclick(providedCallback: hintClickCallback): IntroJs;
244
245
type hintClickCallback = (
246
this: IntroJs,
247
hintElement: HTMLElement,
248
item: HintStep,
249
stepId: number
250
) => void | Promise<void>;
251
```
252
253
#### Hint Close Callback
254
255
Called when a hint is closed.
256
257
```typescript { .api }
258
/**
259
* Register callback for hint close
260
* @param providedCallback - Function called when hint is closed
261
* @returns IntroJs instance for chaining
262
*/
263
onhintclose(providedCallback: hintCloseCallback): IntroJs;
264
265
type hintCloseCallback = (
266
this: IntroJs,
267
stepId: number
268
) => void | Promise<void>;
269
```
270
271
**Usage Examples:**
272
273
```typescript
274
// Hint system callbacks
275
const intro = introJs()
276
.onhintsadded(function() {
277
console.log("Hints have been added to the page");
278
// Initialize hint tracking
279
initializeHintTracking();
280
})
281
.onhintclick(function(hintElement, item, stepId) {
282
console.log(`Hint ${stepId} clicked:`, item);
283
// Track hint interaction
284
analytics.track("hint_clicked", {
285
step_id: stepId,
286
hint_text: item.hint
287
});
288
})
289
.onhintclose(function(stepId) {
290
console.log(`Hint ${stepId} closed`);
291
// Track hint dismissal
292
analytics.track("hint_closed", { step_id: stepId });
293
});
294
295
// Set up hints and add callbacks
296
intro.setOptions({
297
hints: [
298
{ element: "#feature1", hint: "Try this feature!" },
299
{ element: "#feature2", hint: "Don't forget about this!" }
300
]
301
});
302
303
await intro.addHints();
304
await intro.showHints();
305
```
306
307
## Callback Patterns
308
309
### Async Callback Handling
310
311
Handle asynchronous operations in callbacks.
312
313
**Usage Examples:**
314
315
```typescript
316
const intro = introJs()
317
.onbeforechange(async function(targetElement, currentStep, direction) {
318
// Async validation
319
const isValid = await validateStepAsync(currentStep);
320
if (!isValid) {
321
await showValidationError();
322
return false;
323
}
324
return true;
325
})
326
.onchange(async function(targetElement) {
327
// Load data for current step
328
await loadStepData(targetElement.id);
329
})
330
.oncomplete(async function(currentStep, reason) {
331
// Save completion to server
332
await saveUserProgress({
333
completed_steps: currentStep,
334
completion_reason: reason,
335
timestamp: new Date()
336
});
337
});
338
```
339
340
### Conditional Logic in Callbacks
341
342
Implement branching logic based on callback parameters.
343
344
**Usage Examples:**
345
346
```typescript
347
const intro = introJs()
348
.onbeforechange(function(targetElement, currentStep, direction) {
349
// Different logic for different steps
350
switch (currentStep) {
351
case 1:
352
if (direction === "forward") {
353
return validateFirstStep();
354
}
355
break;
356
case 3:
357
if (direction === "backward") {
358
// Clean up step 3 state when going back
359
cleanupStepThree();
360
}
361
break;
362
}
363
return true;
364
})
365
.onchange(function(targetElement) {
366
// Conditional behavior based on element
367
if (targetElement.classList.contains("form-step")) {
368
enableFormValidation();
369
} else if (targetElement.classList.contains("demo-step")) {
370
startDemo();
371
}
372
})
373
.oncomplete(function(currentStep, reason) {
374
// Different actions based on completion reason
375
switch (reason) {
376
case "done":
377
showSuccessMessage();
378
break;
379
case "skip":
380
showSkipFeedback();
381
break;
382
case "end":
383
showCompletionReward();
384
break;
385
}
386
});
387
```
388
389
### Error Handling in Callbacks
390
391
Proper error handling for callback functions.
392
393
**Usage Examples:**
394
395
```typescript
396
const intro = introJs()
397
.onbeforechange(function(targetElement, currentStep, direction) {
398
try {
399
const isValid = validateStep(currentStep);
400
return isValid;
401
} catch (error) {
402
console.error("Validation error:", error);
403
showErrorMessage("Validation failed. Please try again.");
404
return false;
405
}
406
})
407
.onchange(async function(targetElement) {
408
try {
409
await updateUIForStep(targetElement);
410
} catch (error) {
411
console.error("UI update failed:", error);
412
// Continue tour even if UI update fails
413
}
414
})
415
.oncomplete(async function(currentStep, reason) {
416
try {
417
await trackCompletion(currentStep, reason);
418
} catch (error) {
419
console.error("Analytics tracking failed:", error);
420
// Don't prevent tour completion due to tracking issues
421
}
422
});
423
```
424
425
### State Management with Callbacks
426
427
Use callbacks to manage application state during tours.
428
429
**Usage Examples:**
430
431
```typescript
432
let tourState = {
433
startTime: null,
434
stepTimes: [],
435
userInteractions: []
436
};
437
438
const intro = introJs()
439
.onstart(function() {
440
tourState.startTime = Date.now();
441
setTourMode(true);
442
})
443
.onbeforechange(function(targetElement, currentStep, direction) {
444
tourState.stepTimes[currentStep] = Date.now();
445
return true;
446
})
447
.onchange(function(targetElement) {
448
// Update app state for current step
449
updateAppState({
450
currentTourStep: this.currentStep(),
451
targetElement: targetElement.id
452
});
453
})
454
.oncomplete(function(currentStep, reason) {
455
const totalTime = Date.now() - tourState.startTime;
456
saveTourAnalytics({
457
...tourState,
458
totalTime,
459
completionReason: reason
460
});
461
setTourMode(false);
462
})
463
.onexit(function() {
464
setTourMode(false);
465
resetAppState();
466
});
467
```