0
# NativeView
1
2
NativeView is a foundational class that extends Backbone.View with native DOM event delegation, providing enhanced performance and modern DOM handling capabilities. It serves as the base class for WidgetView and other view components.
3
4
## Capabilities
5
6
### NativeView Class
7
8
Enhanced Backbone.View with native DOM event delegation and element manipulation utilities.
9
10
```typescript { .api }
11
/**
12
* Native DOM view implementation extending Backbone.View
13
* Provides enhanced event delegation using native DOM methods
14
*/
15
class NativeView<T extends Backbone.Model> extends Backbone.View<T> {
16
/**
17
* Delegate event listeners using native DOM methods
18
* @param eventName - DOM event name (e.g., 'click', 'change')
19
* @param listener - Event handler function
20
* @returns This view instance for chaining
21
*/
22
delegate(eventName: string, listener: Function): this;
23
24
/**
25
* Delegate event listeners with CSS selector
26
* @param eventName - DOM event name
27
* @param selector - CSS selector for event delegation
28
* @param listener - Event handler function
29
* @returns This view instance for chaining
30
*/
31
delegate(eventName: string, selector: string, listener: Function): this;
32
33
/**
34
* Remove delegated event listener
35
* @param eventName - DOM event name to remove
36
* @param selector - Optional CSS selector
37
* @param listener - Optional specific listener to remove
38
* @returns This view instance for chaining
39
*/
40
undelegate(eventName: string, selector?: string, listener?: Function): this;
41
42
/**
43
* Remove delegated event listener by selector
44
* @param selector - CSS selector
45
* @param listener - Optional specific listener to remove
46
* @returns This view instance for chaining
47
*/
48
undelegate(selector: string, listener?: Function): this;
49
50
/**
51
* Remove all delegated event listeners from the element
52
* @returns This view instance for chaining
53
*/
54
undelegateEvents(): this;
55
56
/**
57
* Remove the view's element from the DOM and clean up events
58
*/
59
_removeElement(): void;
60
61
/**
62
* Set the DOM element for this view
63
* @param element - HTML element to attach to this view
64
*/
65
_setElement(element: HTMLElement): void;
66
67
/**
68
* Set attributes on the view's element
69
* @param attrs - Hash of attributes to set
70
*/
71
_setAttributes(attrs: Backbone.ObjectHash): void;
72
}
73
```
74
75
**Usage Examples:**
76
77
```typescript
78
import { NativeView } from "@jupyter-widgets/base";
79
80
// Create a custom view extending NativeView
81
class MyCustomView extends NativeView<MyModel> {
82
initialize() {
83
// Delegate click events to buttons within this view
84
this.delegate('click', 'button', this.handleButtonClick);
85
86
// Delegate change events with selector
87
this.delegate('change', 'input[type="text"]', this.handleTextChange);
88
89
// Delegate without selector (binds to this.el)
90
this.delegate('keydown', this.handleKeyDown);
91
}
92
93
handleButtonClick(event: Event) {
94
const button = event.delegateTarget as HTMLButtonElement;
95
console.log('Button clicked:', button.textContent);
96
}
97
98
handleTextChange(event: Event) {
99
const input = event.delegateTarget as HTMLInputElement;
100
this.model.set('text_value', input.value);
101
}
102
103
handleKeyDown(event: KeyboardEvent) {
104
if (event.key === 'Escape') {
105
this.remove();
106
}
107
}
108
109
remove() {
110
// Clean up all delegated events
111
this.undelegateEvents();
112
113
// Remove specific event
114
this.undelegate('click', 'button');
115
116
return super.remove();
117
}
118
}
119
120
// Manual event management
121
const view = new MyCustomView();
122
123
// Add event delegation
124
view.delegate('mouseover', '.tooltip-trigger', (e) => {
125
showTooltip(e.delegateTarget);
126
});
127
128
// Remove specific delegated event
129
view.undelegate('mouseover', '.tooltip-trigger');
130
131
// Remove all events for cleanup
132
view.undelegateEvents();
133
```
134
135
## Advanced Event Delegation
136
137
### CSS Selector Support
138
139
NativeView supports full CSS selector syntax for event delegation:
140
141
```typescript
142
// Class selectors
143
view.delegate('click', '.button-primary', handlePrimaryClick);
144
145
// Attribute selectors
146
view.delegate('change', 'input[data-validate]', handleValidation);
147
148
// Descendant selectors
149
view.delegate('click', '.panel .close-button', handlePanelClose);
150
151
// Pseudo-selectors
152
view.delegate('focus', 'input:not([readonly])', handleFocus);
153
```
154
155
### Event Object Enhancement
156
157
When using delegated events with selectors, the event object is enhanced:
158
159
```typescript
160
view.delegate('click', '.item', function(event) {
161
// event.delegateTarget is the element matching the selector
162
const item = event.delegateTarget as HTMLElement;
163
164
// event.target is the actual clicked element (may be a child)
165
const clickedElement = event.target as HTMLElement;
166
167
console.log('Clicked on', clickedElement, 'within', item);
168
});
169
```
170
171
## Performance Benefits
172
173
NativeView provides several performance advantages:
174
175
- **Native Event Delegation**: Uses `addEventListener` instead of jQuery-style delegation
176
- **Efficient Selector Matching**: Leverages native `Element.matches()` with fallbacks
177
- **Memory Management**: Proper cleanup of event listeners to prevent memory leaks
178
- **Cross-browser Compatibility**: Handles vendor prefixes and IE9+ compatibility
179
180
## Browser Compatibility
181
182
NativeView includes fallbacks for older browsers:
183
184
- Modern browsers: Uses `Element.matches()`
185
- Webkit: Uses `webkitMatchesSelector`
186
- Mozilla: Uses `mozMatchesSelector`
187
- Microsoft: Uses `msMatchesSelector`
188
- Opera: Uses `oMatchesSelector`
189
- IE9+: Uses `querySelectorAll` fallback
190
191
## Migration from Backbone.View
192
193
When extending NativeView instead of Backbone.View:
194
195
```typescript
196
// Old Backbone.View approach
197
class OldView extends Backbone.View {
198
events: {
199
'click button': 'handleClick',
200
'change input': 'handleChange'
201
}
202
203
handleClick(e) { /* ... */ }
204
handleChange(e) { /* ... */ }
205
}
206
207
// New NativeView approach
208
class NewView extends NativeView {
209
initialize() {
210
this.delegate('click', 'button', this.handleClick);
211
this.delegate('change', 'input', this.handleChange);
212
}
213
214
handleClick(e) { /* ... */ }
215
handleChange(e) { /* ... */ }
216
}
217
```
218
219
The NativeView approach provides more explicit control over event delegation and better performance with native DOM methods.