@@ -13,7 +13,7 @@ level features to structure sites and apps. But it also is easy to end up with
13
13
div soup once you start implementing a complex component using native HTML tags.
14
14
What if the web platform could allow you to create your original component?
15
15
What if you can give it an arbitrary tag name? What if you can extend features
16
- of an existing HTML tag?
16
+ of an existing HTML tag?
17
17
Custom Elements allow you to do those things.
18
18
19
19
<!-- Excerpt -->
@@ -38,12 +38,12 @@ its tag name as the first argument.
38
38
var XComponent = document.registerElement('x-component');
39
39
```
40
40
41
- Now you can use ` <x-component> ` wherever you want in the document.
41
+ Now you can use ` <x-component> ` wherever you want in the document.
42
42
43
43
```
44
44
<x-component></x-component>
45
45
```
46
-
46
+
47
47
Note: ` <x-component> ` can appear in the document before the definition of the
48
48
custom element execution. See
49
49
[ HTML5Rocks article] ( http://www.html5rocks.com/en/tutorials/webcomponents/customelements/ )
@@ -62,13 +62,13 @@ polyfill it.
62
62
63
63
You need to have at least one '` - ` ' inside the name of a custom element. Any tag
64
64
names without '` - ` ' will result in an error.
65
-
66
- Good
65
+
66
+ Good
67
67
68
68
* x-component
69
69
* x-web-component
70
70
71
- Bad
71
+ Bad
72
72
73
73
* web_component
74
74
* xelement
@@ -84,30 +84,30 @@ var XComponent = document.registerElement('x-component');
84
84
var dom = new XComponent();
85
85
document.body.appendChild(dom);
86
86
```
87
-
88
- The above example is using ` new ` to instantiate a custom element.
87
+
88
+ The above example is using ` new ` to instantiate a custom element.
89
89
90
90
```
91
91
document.registerElement('x-component');
92
92
var dom = document.createElement('x-component');
93
93
document.body.appendChild(dom);
94
94
```
95
-
96
- This example uses ` document.createElement() ` to instantiate a custom element.
95
+
96
+ This example uses ` document.createElement() ` to instantiate a custom element.
97
97
98
98
# Adding features to a custom element
99
99
100
100
Being able to use a custom tag name itself is fine, but it doesn't do much.
101
101
Let's add some features to the element.
102
-
102
+
103
103
In order to add features to a custom element, you first need to create a basic
104
104
prototype object by calling ` Object.create() ` with ` HTMLElement.prototype ` as an
105
105
argument. This gives you an empty prototype object with the basic HTML element
106
106
feature set in its prototype chain. Add any functions and properties you want to
107
107
the prototype object, then pass your prototype to document.registerElement as
108
108
shown below:
109
109
110
- ```
110
+ ```
111
111
var proto = Object.create(HTMLElement.prototype);
112
112
proto.name = 'Custom Element';
113
113
proto.alert = function() {
@@ -124,7 +124,7 @@ Let's see what's going on in a custom element using Chrome DevTools. Use the
124
124
"Elements" panel to inspect the ` x-component ` tag we just created. You can see
125
125
the ` x-component ` is an instance of a ` x-component ` prototype which is an
126
126
instance of the ` HTMLElement ` prototype.
127
-
127
+
128
128
![ Custom Element Structure] ( /img/stories/customelements-inherit.png )
129
129
130
130
# Type Extension Custom Element
@@ -133,17 +133,17 @@ You can create a custom element that extends a native HTML element's features.
133
133
This is called a Type Extension Custom Element. To use the element, use the
134
134
original tag and specify the custom tag name using the '` is ` ' attribute.
135
135
136
- ```
136
+ ```
137
137
<div is="x-component"></div>
138
138
```
139
-
139
+
140
140
To define a type extension:
141
141
142
- - Create the base prototype object using the prototype of the extended element,
142
+ - Create the base prototype object using the prototype of the extended element,
143
143
instead of HTMLElement.
144
- - Add an ` extends ` key in the second argument to ` document.registerElement() ` ,
144
+ - Add an ` extends ` key in the second argument to ` document.registerElement() ` ,
145
145
specifying the * tag name* of the extended element.
146
-
146
+
147
147
Following is an example code when extending the ` input ` element:
148
148
149
149
```
@@ -152,12 +152,12 @@ var XComponent = document.registerElement('x-component', {
152
152
prototype: Object.create(HTMLInputElement.prototype)
153
153
});
154
154
```
155
-
155
+
156
156
Notice that it ` extends: 'input' ` and its prototype is based on
157
157
` HTMLInputElement ` instead of ` HTMLElement ` . Now you can use
158
158
` <input is="x-component"> ` inside your document. By doing so, you can have
159
159
extended APIs on top of basic ` input ` element's features.
160
-
160
+
161
161
Note: You may wonder what happens if you set different elements for ` 'extends ` '
162
162
and '` prototype ` '. Yes, it is possible and may cause unexpected results. But as
163
163
far as I have experimented, you won't get any valuable outcome.
@@ -166,60 +166,60 @@ far as I have experimented, you won't get any valuable outcome.
166
166
167
167
So what's the point of Type Extension Custom Element? Let's look at a great
168
168
existing example at the GitHub website.
169
-
170
- ![ relative-time type extension] ( /img/stories/customelements-relativetime.png )
171
-
169
+
170
+ ![ relative-time type extension] ( /img/stories/customelements-relativetime.png )
171
+
172
172
GitHub has a many components that displays date and time. Notice they are not
173
173
absolute dates/times but relative to the browser's current time.
174
174
You should be able to imagine how to calculate that but GitHub is doing that
175
175
using Type Extension Custom Element with [ `time-
176
176
elements`] ( https://github.com/github/time-elements ) .
177
-
178
- Let's look into how it works.
179
-
180
- ![ time element] ( /img/stories/customelements-time.png )
181
-
182
- There are four things you should notice:
177
+
178
+ Let's look into how it works.
179
+
180
+ ![ time element] ( /img/stories/customelements-time.png )
181
+
182
+ There are four things you should notice:
183
183
184
184
* ` time ` tag is used as a base element
185
185
* ` datetime ` attribute indicates an absolute date/time
186
186
* ` relative-time ` is specified as a type extension
187
187
* ` TextContent ` indicates a relative date/time
188
-
188
+
189
189
This is done by calculating a relative date/time out from an absolute date/time
190
190
(` datetime ` ) attribute on the fly as a type extension.
191
-
191
+
192
192
The benefit of using Type Extension Custom Element is that even if JavaScript is
193
193
turned off or the browser doesn't support Custom Elements (including polyfill),
194
194
the ` time ` element will still show the date/time information as a fallback
195
195
keeping its semantics. Try using DevTools and turning off JavaScript; you'll
196
196
notice it shows absolute dates and times.
197
-
197
+
198
198
Read webcomponents.org's
199
199
[ How GitHub is using Web Components in production] ( http://webcomponents.org/articles/interview-with-joshua-peek/ )
200
- for more details about ` time-elements ` .
200
+ for more details about ` time-elements ` .
201
201
202
202
# Lifecycle callbacks
203
203
204
204
I mentioned the ` relative-time ` custom element inserts a relative date/time into
205
205
` TextContent ` on the fly. But when does that happen? You can define functions to
206
206
be called when certain events happened on Custom Elements, which are called
207
207
"lifecycle callbacks".
208
-
209
- Here's the list of lifecycle callbacks:
210
-
211
- ** .createdCallback()**
208
+
209
+ Here's the list of lifecycle callbacks:
210
+
211
+ ** .createdCallback()**
212
212
Called after the element is created.
213
213
214
- ** .attachedCallback()**
214
+ ** .attachedCallback()**
215
215
Called when the element is attached to the document
216
216
217
- ** .detachedCallback()**
217
+ ** .detachedCallback()**
218
218
Called when the element is detached from the document.
219
219
220
- ** .attributeChangedCallback()**
220
+ ** .attributeChangedCallback()**
221
221
Called when one of attributes of the element is changed.
222
-
222
+
223
223
In case of ` relative-time ` , ` .createdCallback() ` and
224
224
` .attributeChangedCallback() ` are hooked up to insert a relative date/time to
225
225
` TextContent ` .
@@ -229,7 +229,7 @@ In case of `relative-time`, `.createdCallback()` and
229
229
To use lifecycle callbacks, just define the functions as properties of a
230
230
prototype object when registering a custom element.
231
231
232
- ```
232
+ ```
233
233
var proto = Object.create(HTMLElement.prototype);
234
234
proto.createdCallback = function() {
235
235
var div = document.createElement('div');
@@ -254,7 +254,7 @@ read the respective articles
254
254
([ Template] ( http://webcomponents.org/articles/introduction-to-template-element ) ,
255
255
[ Shadow DOM] ( http://webcomponents.org/articles/introduction-to-shadow-dom ) )
256
256
written previously.
257
-
257
+
258
258
** HTML**
259
259
```
260
260
<!-- Template Definition -->
@@ -291,7 +291,7 @@ var XComponent = document.registerElement('x-component', {
291
291
prototype: proto
292
292
});
293
293
```
294
-
294
+
295
295
[ Here's a live example.] ( http://jsbin.com/yugoka/3/edit?html,js,output )
296
296
297
297
# Supported browsers
@@ -309,9 +309,9 @@ from [platform.js](https://github.com/Polymer/platform)).
309
309
So that's the Custom Elements.
310
310
[ As you may have noticed] ( http://webcomponents.org/articles/interview-with-joshua-peek/ )
311
311
, Custom Elements are used in the production of GitHub supporting IE9 by using
312
- polyfill. Now is your time to try this feature.
313
-
314
- If you are interested in learning more about the Custom Elements, head over to:
312
+ polyfill. Now is your time to try this feature.
313
+
314
+ If you are interested in learning more about the Custom Elements, head over to:
315
315
316
316
* [ Custom Elements: defining new elements in HTML - HTML5Rocks] ( http://goo.gl/ozdC4Q )
317
317
* [ Custom Elements spec] ( http://w3c.github.io/webcomponents/spec/custom/ )
0 commit comments