1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
|
---
title: Benutzerdefinierte Elemente
slug: Web/Web_Components/Custom_Elements
translation_of: Web/Web_Components/Using_custom_elements
translation_of_original: Web/Web_Components/Custom_Elements
---
<p>Benutzerdefinierte Elemente sind stellen die Möglichkeit bereit, benutzerdefinierte HTML-<a href="/en-US/docs/Glossary/Element">Elements</a> zu schaffen. Sie können eigenes durch JavaScript beschriebenes Verhalten und CSS-Styling haben. Sie sind Teil der <a href="/en-US/docs/Web/Web_Components">Web-Components</a>, können aber auch unabhängig von diesen benutzt werden.</p>
<div class="note">
<p><strong>Note:</strong> Benutzerdefinierte Elemente gelten erst seit Kurzem als stabil definiert und Teile des MDN weisen Dokumentation für veraltete APIs früherer Spezifikationsentwürfe auf.</p>
</div>
<p>Obwohl es bereits möglich war, benutzerdefinierte Tag-Namen wie <code><mytag></code> zu schaffen, sie mit CSS zu stylen und via JavaScript ihr Verhalten zu beschreiben, haben benutzerdefinierte Elemente ihre Daseinsberechtigung. Ihr großer Vorteil ist das Vorhandensein so genannter <em>Lebenszyklus-Reaktionen</em>, die es erlauben, Methoden zu bestimmten Momenten des "Lebenszyklus" des Elementes aufzurufen. So kann beispielsweise Verhalten beschrieben werden, dass ausgeführt wird, wenn das Element dem DOM hinzugefügt wird ("connected"), wenn es aus diesem entfernt wird ("disconnected") oder sich seine Attribute ändern.</p>
<p>Die Schlüsselmethode für benutzerdefinierte Elemente ist die {{domxref("CustomElementRegistry.define()")}}-Methode, die benutzt werden kann, um ein neues benutzerdefinierte Elemente zu erschaffen. Dieses neue Element wird dann für jede seiner Instanzen diese neue Klasse anstelle des standardmäßig verwendeten {{domxref("HTMLUnknownElement")}} benutzen. Benutzerdefinierte Elemente können auch auf nativen Elementen wie <code><button></code> basieren, indem sie folgende Syntax benutzen: <code><button is="my-button"></code> Sie werden dann <em>benutzerdefinierte eingebaute Elemente </em>genannt.</p>
<h2 id="Methoden_benutzerdefinierter_Elemente">Methoden benutzerdefinierter Elemente</h2>
<p>Benutzerdefinierte Elemente besitzen folgende Methoden:</p>
<dl>
<dt>constructor()</dt>
<dd>Wird aufgerufen, wenn eine Element erzeugt und erweitert wird.</dd>
<dt>connectedCallback()</dt>
<dd>Wird aufgerufen, wenn das Element in das Dokument eingefügt wird, auch wenn es nur der Shadow Tree ist</dd>
<dt>disconnectedCallback()</dt>
<dd>Wird aufgerufen, wenn das Element aus dem Dokument entfernt wird.</dd>
<dt>attributeChangedCallback(attributeName, oldValue, newValue, namespace)</dt>
<dd>Wird aufgerufen, wenn Attribute des Elements geändert, angefügt, entfernt oder ersetzt werden. Wird nur für <a href="#Observed_attributes">beobachtete Attribute</a> aufgerufen.</dd>
<dt>adoptedCallback(oldDocument, newDocument)</dt>
<dd>Wird aufgerufen, wenn das Element in ein neues Dokument übernommen wird.</dd>
</dl>
<h2 id="Beispiele">Beispiele</h2>
<p>Benutzerdefinierte Elemente müssen die <a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes"><code>class</code> Syntax</a> benutzen, die in neueren JavaScript-Versionen bereit steht.</p>
<p>HTML-Datei:</p>
<pre class="brush: html">Wenn unter diesem Text nichts steht, unterstützt ihr Browser keine benutzerdefinierten Elemente.
<x-product data-name="Ruby" data-img="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4621/ruby.png" data-url="http://example.com/1"></x-product>
<x-product data-name="JavaScript" data-img="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4621/javascript.png" data-url="http://example.com/2"></x-product>
<x-product data-name="Python" data-img="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4621/python.png" data-url="http://example.com/3"></x-product></pre>
<p>JS-Datei:</p>
<pre class="brush: js">// Klasse für das Element erzeugen
class XProduct extends HTMLElement {
constructor() {
// super() muss immer als erstes im Konstruktor aufgerufen werden
super();
// Shadow-Root erzeugen
var shadow = this.attachShadow({mode: 'open'});
// Standard img-Element erzeugen und Attribute setzen
var img = document.createElement('img');
img.alt = this.getAttribute('data-name');
img.src = this.getAttribute('data-img');
img.width = '150';
img.height = '150';
img.className = 'product-img';
// Bild der Shadow-Root hinzufügen.
shadow.appendChild(img);
// Event-Listener zum Bild hinzufügen.
img.addEventListener('click', () => {
window.location = this.getAttribute('data-url');
});
// Link zum Produkt erzeugen.
var link = document.createElement('a');
link.innerText = this.getAttribute('data-name');
link.href = this.getAttribute('data-url');
link.className = 'product-name';
// Link der Shadow-Root hinzufügen.
shadow.appendChild(link);
}
}
// Neues Element definieren
customElements.define('x-product', XProduct);
</pre>
<p>CSS-Datei:</p>
<pre class="brush: css">body {
background: #F7F7F7;
}
x-product {
display: inline-block;
float: left;
margin: 0.5em;
border-radius: 3px;
background: #FFF;
box-shadow: 0 1px 3px rgba(0,0,0,0.25);
font-family: Helvetica, arial, sans-serif;
-webkit-font-smoothing: antialiased;
}
x-product::slotted(.product-img) {
cursor: pointer;
background: #FFF;
margin: 0.5em;
}
x-product::slotted(.product-name) {
display: block;
text-align: center;
text-decoration: none;
color: #08C;
border-top: 1px solid #EEE;
font-weight: bold;
padding: 0.75em 0;
}
</pre>
<p><a id="live_example" name="live_example">Unten kann das Live-Beispiel des obigen Codes gesehen werden:</a></p>
<p>{{ EmbedLiveSample('Example', '1500', '250', '', 'Web/Web_Components/Custom_Elements') }}</p>
<h2 id="Beobachtete_Attribute">Beobachtete Attribute</h2>
<p>Um benachrichtigt zu werden, wenn Attribute verändert werden, muss eine Liste von beobachteten Attributen bei der Initialisierung des Elements angelegt werden, in dem eine statische <code>observedAttributes</code> get-Methode der Klasse des Elementes hinzugefügt wird, die ein Array mit den entsprechenden Attributsnamen zurückgibt.</p>
<p>JS-Datei:</p>
<pre class="brush: js">class HelloElement extends HTMLElement {
// Das 'name'-Attribut beobachten.
static get observedAttributes() {return ['name']; }
// Auf Attributsänderungen reagieren.
attributeChangedCallback(attr, oldValue, newValue) {
if (attr == 'name') {
this.textContent = `Hello, ${newValue}`;
}
}
}
// Neues Element definieren
customElements.define('hello-element', HelloElement);
</pre>
<p>HTML-Datei:</p>
<pre class="brush: html"><hello-element name="Anita"></hello-element></pre>
<p><a id="live_example" name="live_example">Unten kann das Live-Beispiel des obigen Codes gesehen werden:</a></p>
<p>{{ EmbedLiveSample('Observed_attributes', '750', '100', '', 'Web/Web_Components/Custom_Elements') }}</p>
<h2 id="Spezifikationen">Spezifikationen</h2>
<p>Benutzerdefinierte Elemente sind in der folgenden Spezifikation definiert:</p>
<table class="spec-table standard-table">
<tbody>
<tr>
<th scope="col">Spezifikation</th>
<th scope="col">Status</th>
<th scope="col">Kommentar</th>
</tr>
<tr>
<td><a href="https://html.spec.whatwg.org/multipage/scripting.html#custom-elements">The HTML Standard: Custom elements</a></td>
<td>LS</td>
<td> </td>
</tr>
</tbody>
</table>
<h2 id="Browserkompatibilität">Browserkompatibilität</h2>
<p>{{CompatibilityTable}}</p>
<div id="compat-desktop">
<table class="compat-table">
<tbody>
<tr>
<th>Feature</th>
<th>Firefox (Gecko)</th>
<th>Chrome</th>
<th>Internet Explorer</th>
<th>Opera</th>
<th>Safari</th>
</tr>
<tr>
<td>Grundlegende Unterstützung</td>
<td>{{CompatNo}}</td>
<td>{{CompatChrome(59.0)}}</td>
<td>{{CompatNo}}</td>
<td>{{CompatOpera(47.0)}}</td>
<td>10.1</td>
</tr>
<tr>
<td>Benutzerdefinierte eingebaute Elemente</td>
<td>{{CompatNo}}</td>
<td>{{CompatChrome(59.0)}}</td>
<td>{{CompatNo}}</td>
<td>{{CompatOpera(47.0)}}</td>
<td>{{CompatNo}}</td>
</tr>
</tbody>
</table>
</div>
<div id="compat-mobile">
<table class="compat-table">
<tbody>
<tr>
<th>Feature</th>
<th>Firefox Mobile (Gecko)</th>
<th>Chrome for Android</th>
<th>IE Mobile</th>
<th>Opera Mobile</th>
<th>Safari Mobile</th>
</tr>
<tr>
<td>Grundlegende Unterstützung</td>
<td>{{CompatNo}}</td>
<td>{{CompatChrome(56.0)}}</td>
<td>{{CompatNo}}</td>
<td>{{CompatOpera(47.0)}}</td>
<td>10.1</td>
</tr>
<tr>
<td>Benutzerdefinierte eingebaute Elemente</td>
<td>{{CompatNo}}</td>
<td>{{CompatChrome(56.0)}}</td>
<td>{{CompatNo}}</td>
<td>{{CompatOpera(47.0)}}</td>
<td>{{CompatNo}}</td>
</tr>
</tbody>
</table>
</div>
<p>1. Firefox hat eine "dom.webcomponents.enabled"-Eigenschaft in about:config, dennoch ist sind benutzerdefinierte Elemente nicht verfügbar, wenn diese auf <strong>true</strong> gesetzt wurde.</p>
<h2 id="Related">Related</h2>
<ul>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry">The Custom Element Registry</a>
<ul>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/define">define()</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/get">get()</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/whenDefined">whenDefined()</a></li>
</ul>
</li>
</ul>
<h2 id="Resources">Resources</h2>
<ul>
<li><a href="https://developers.google.com/web/fundamentals/primers/customelements/">Custom elements v1: reusable web components - Google Developers tutorial</a></li>
</ul>
|