0
# Event Delegation
1
2
Advanced event delegation system for handling tooltips on dynamically created elements and managing large sets of tooltip triggers efficiently.
3
4
## Capabilities
5
6
### Delegate Function
7
8
Creates delegate instances that automatically handle tooltip creation for child elements matching a CSS selector, perfect for dynamic content and large element sets.
9
10
```typescript { .api }
11
/**
12
* Creates a delegate instance that controls tooltip creation for child elements
13
* @param targets - Parent elements to monitor for delegation
14
* @param props - Tooltip properties including required target selector
15
* @returns Delegate instance(s) with enhanced destroy method
16
*/
17
function delegate(
18
targets: Element | Element[] | NodeList | string,
19
props: Partial<Props> & { target: string }
20
): DelegateInstance | DelegateInstance[];
21
22
interface DelegateInstance<TProps = Props> extends Instance<TProps> {
23
/** Destroy delegate and optionally destroy target instances */
24
destroy(shouldDestroyTargetInstances?: boolean): void;
25
}
26
```
27
28
**Usage Examples:**
29
30
```typescript
31
import { delegate } from "tippy.js";
32
33
// Basic delegation for dynamically added elements
34
const delegateInstance = delegate('#container', {
35
target: '.tooltip-target', // CSS selector for child elements
36
content: 'Delegated tooltip',
37
placement: 'top'
38
});
39
40
// Add elements dynamically - tooltips are created automatically
41
const container = document.querySelector('#container');
42
container.innerHTML += '<button class="tooltip-target">New Button</button>';
43
44
// Delegation with dynamic content
45
delegate('.list-container', {
46
target: '.list-item',
47
content(reference) {
48
return reference.getAttribute('data-tooltip') || 'Default content';
49
},
50
allowHTML: true
51
});
52
53
// Multiple containers with shared configuration
54
delegate(['.sidebar', '.main-content'], {
55
target: '[data-tippy]',
56
content(reference) {
57
return reference.dataset.tippy;
58
},
59
placement: 'auto'
60
});
61
```
62
63
### Dynamic Element Handling
64
65
Automatic tooltip creation and cleanup for elements that are added or removed from the DOM after delegation is set up.
66
67
```typescript { .api }
68
// Delegation automatically handles:
69
// - Elements added after delegation setup
70
// - Different trigger types per element (via data attributes)
71
// - Custom content per element
72
// - Cleanup when elements are removed
73
```
74
75
**Usage Examples:**
76
77
```typescript
78
import { delegate } from "tippy.js";
79
80
// Set up delegation for a dynamic list
81
const listDelegate = delegate('#dynamic-list', {
82
target: '.list-item',
83
content(reference) {
84
return `Item: ${reference.textContent}`;
85
},
86
trigger: 'mouseenter focus'
87
});
88
89
// Elements added later automatically get tooltips
90
function addListItem(text) {
91
const item = document.createElement('div');
92
item.className = 'list-item';
93
item.textContent = text;
94
document.querySelector('#dynamic-list').appendChild(item);
95
// Tooltip is automatically available on this new element
96
}
97
98
// Different triggers per element using data attributes
99
delegate('#mixed-triggers', {
100
target: '.interactive-element',
101
content: 'Flexible tooltip',
102
// Individual elements can override trigger via data-tippy-trigger
103
});
104
105
// HTML in list:
106
// <div class="interactive-element" data-tippy-trigger="click">Click me</div>
107
// <div class="interactive-element" data-tippy-trigger="mouseenter">Hover me</div>
108
```
109
110
### Delegate Instance Management
111
112
Enhanced instance management with child tooltip control and bulk operations.
113
114
```typescript { .api }
115
interface DelegateInstance<TProps = Props> extends Instance<TProps> {
116
/** Standard instance methods inherited */
117
show(): void;
118
hide(): void;
119
enable(): void;
120
disable(): void;
121
destroy(shouldDestroyChildInstances?: boolean): void;
122
}
123
```
124
125
**Usage Examples:**
126
127
```typescript
128
import { delegate } from "tippy.js";
129
130
const delegateInstance = delegate('#parent', {
131
target: '.child',
132
content: 'Child tooltip'
133
});
134
135
// Control all child tooltips via delegate
136
delegateInstance.enable(); // Enable all child tooltips
137
delegateInstance.disable(); // Disable all child tooltips
138
139
// Destroy with options
140
delegateInstance.destroy(true); // Destroy delegate and all child instances
141
delegateInstance.destroy(false); // Destroy delegate but keep child instances
142
143
// The delegate instance itself can be shown/hidden
144
delegateInstance.show(); // This won't work as expected - delegates don't have their own tooltip
145
```
146
147
### Performance Optimization
148
149
Delegation provides significant performance benefits for large numbers of elements by using event bubbling instead of individual event listeners.
150
151
```typescript { .api }
152
// Performance comparison:
153
// Individual tooltips: N event listeners for N elements
154
// Delegated tooltips: 4 event listeners total (touch, mouse, focus, click)
155
```
156
157
**Usage Examples:**
158
159
```typescript
160
import { delegate } from "tippy.js";
161
162
// Efficient for large tables
163
delegate('#data-table', {
164
target: 'td[data-tooltip]',
165
content(reference) {
166
return reference.dataset.tooltip;
167
},
168
delay: [500, 100] // Reduce accidental triggers
169
});
170
171
// Efficient for dynamic grids
172
delegate('.image-grid', {
173
target: '.image-item',
174
content(reference) {
175
const img = reference.querySelector('img');
176
return `
177
<div>
178
<strong>${img.alt}</strong><br>
179
${img.dataset.description || 'No description'}
180
</div>
181
`;
182
},
183
allowHTML: true,
184
placement: 'bottom'
185
});
186
187
// Memory efficient infinite scroll
188
const infiniteDelegate = delegate('#infinite-scroll', {
189
target: '.scroll-item',
190
content: 'Tooltip for scroll item'
191
});
192
193
// No need to manage tooltips when items are removed/added
194
// Delegation handles it automatically
195
```
196
197
### Advanced Delegation Patterns
198
199
Complex delegation scenarios with conditional logic and nested delegation.
200
201
**Usage Examples:**
202
203
```typescript
204
import { delegate } from "tippy.js";
205
206
// Conditional delegation based on element state
207
delegate('#conditional-container', {
208
target: '.conditional-target',
209
content(reference) {
210
if (reference.classList.contains('disabled')) {
211
return 'This feature is disabled';
212
}
213
return reference.getAttribute('data-help') || 'No help available';
214
},
215
onTrigger(instance, event) {
216
// Additional logic on trigger
217
if (event.target.classList.contains('no-tooltip')) {
218
return; // Skip tooltip creation
219
}
220
}
221
});
222
223
// Nested delegation for complex layouts
224
delegate('#outer-container', {
225
target: '.section',
226
content: 'Section tooltip'
227
});
228
229
delegate('#outer-container', {
230
target: '.section .item',
231
content: 'Item tooltip',
232
placement: 'right'
233
});
234
235
// Context-aware delegation
236
delegate('.context-sensitive', {
237
target: '[data-context-help]',
238
content(reference) {
239
const context = reference.closest('[data-context]')?.dataset.context;
240
const helpKey = reference.dataset.contextHelp;
241
return getContextualHelp(context, helpKey);
242
},
243
interactive: true,
244
allowHTML: true
245
});
246
```