Özel öğeler, web geliştiricilerinin yeni HTML etiketleri tanımlamalarına, mevcut etiketleri genişletmelerine ve yeniden kullanılabilir web bileşenleri oluşturmalarına olanak tanır.
Özel Öğeler ile web geliştiricileri yeni HTML etiketleri oluşturabilir, mevcut HTML etiketlerini güçlendirmek veya diğer geliştiricilerin sahip olduğu bileşenleri genişletmek yazar. API, Google Cloud'un tümünde bileşenleri hakkında daha fazla bilgi edinin. Web'in yeniden kullanılabilir bileşenler oluşturmanın standartlara dayalı bir yolunu ele alacağız. Bu da daha az kod, modüler kod ve her yerde daha fazla üretmek için çalışan ekiplere destek sağlıyorum.
Giriş
Tarayıcı, web uygulamalarını yapılandırmak için bize mükemmel bir araç sunuyor. İnsanların kullanıyor. Bunu duymuş olabilirsiniz. Hem bildirimsel hem de taşınabilir ve kolayca çalışabilmeniz sağlanır. HTML ne kadar iyi olursa, kelime dağarcığı ve genişletilebilirlik sınırlıdır. Canlı HTML standart yaklaşımında daima şimdiye kadar JS davranışını işaretlemenizle otomatik olarak ilişkilendirir.
Özel öğeler, HTML'yi modernleştirmenin ve eksik öğeleri düzeltmenin cevabıdır ve yapıyı davranışla gruplandırmaktır. HTML, yapan özel bir öğe oluşturabiliriz. Özel öğeleri, HTML'nin avantajlarını korurken tarayıcıya yeni numaralar öğretir.
Yeni bir öğe tanımlama
Yeni bir HTML öğesi tanımlamak için JavaScript'in gücüne ihtiyacımız vardır!
customElements
global, özel bir öğeyi tanımlamak ve öğretmek için kullanılır
kontrol edin. Etiket adıyla customElements.define()
çağrısı yapın
ve temel HTMLElement
tabanını genişleten bir JavaScript class
oluşturmak istiyorsunuz.
Örnek - <app-drawer>
mobil çekmece paneli tanımlama:
class AppDrawer extends HTMLElement {...}
window.customElements.define('app-drawer', AppDrawer);
// Or use an anonymous class if you don't want a named constructor in current scope.
window.customElements.define('app-drawer', class extends HTMLElement {...});
Örnek kullanım:
<app-drawer></app-drawer>
Özel öğe kullanmanın
<div>
veya başka bir öğe kullanarak. Örnekler sayfada tanımlanabilir.
JavaScript'te dinamik olarak oluşturulur, etkinlik işleyiciler eklenebilir vb.
daha fazla örnek için okumaya devam edin.
Bir öğenin JavaScript API'sini tanımlama
Özel öğelerin işlevleri ES2015 kullanılarak tanımlanır
class
ve HTMLElement
uzantısına sahip. HTMLElement
işlevinin genişletilmesi, özel öğenin
DOM API'nin tamamını devralır ve
sınıfı, öğenin DOM arayüzünün bir parçası haline gelir. Özetle, sınıfını şu amaçlarla kullanabilirsiniz:
Etiketiniz için herkese açık JavaScript API'si oluşturun.
Örnek - <app-drawer>
öğesinin DOM arayüzünü tanımlama:
class AppDrawer extends HTMLElement {
// A getter/setter for an open property.
get open() {
return this.hasAttribute('open');
}
set open(val) {
// Reflect the value of the open property as an HTML attribute.
if (val) {
this.setAttribute('open', '');
} else {
this.removeAttribute('open');
}
this.toggleDrawer();
}
// A getter/setter for a disabled property.
get disabled() {
return this.hasAttribute('disabled');
}
set disabled(val) {
// Reflect the value of the disabled property as an HTML attribute.
if (val) {
this.setAttribute('disabled', '');
} else {
this.removeAttribute('disabled');
}
}
// Can define constructor arguments if you wish.
constructor() {
// If you define a constructor, always call super() first!
// This is specific to CE and required by the spec.
super();
// Setup a click listener on <app-drawer> itself.
this.addEventListener('click', e => {
// Don't toggle the drawer if it's disabled.
if (this.disabled) {
return;
}
this.toggleDrawer();
});
}
toggleDrawer() {
// ...
}
}
customElements.define('app-drawer', AppDrawer);
Bu örnekte, open
özelliği (disabled
) olan bir çekmece oluşturuyoruz.
özelliği ve bir toggleDrawer()
yöntemi. Ayrıca, özellikleri HTML
özellikleri ile birlikte kullanılamaz.
Özel öğelerin bir diğer güzel özelliği, sınıf tanımı içindeki this
öğesinin
DOM öğesinin kendisi (sınıfın örneği) anlamına gelir. Şurada:
Örneğin this
, <app-drawer>
anlamına gelir. Öğe, bu şekilde (😉)
kendisine bir click
işleyicisi ekleyin! Bunlar etkinlik dinleyicileriyle sınırlı değildir.
DOM API'sinin tamamı öğe kodunun içinde kullanılabilir. Şuna erişmek için this
kullanın:
öğenin özelliklerini, alt öğelerini (this.children
), sorgu düğümlerini inceleyin
(this.querySelectorAll('.items')
) vb.
Özel öğe oluşturma kuralları
- Özel öğenin adı tire (-) içermelidir.
<x-tags>
,<my-element>
ve<my-awesome-app>
geçerli adlardır;<tabs>
ise ve<foo_bar>
değil. Bu gereksinim, HTML ayrıştırıcının özel öğeleri normal öğelerden ayırt edebilirsiniz. Ayrıca ekip üyelerinin yeni etiketler HTML'ye eklendiğinde uyumluluk sağlar. - Aynı etiketi birden çok kez kaydedemezsiniz. Bunu yapmaya çalışırsanız
DOMException
atın. Tarayıcıya yeni bir etiketi bildirdikten sonra, somut olarak ortaya koyar. Geri almak yok. - HTML yalnızca birkaç belleğe izin verdiğinden, özel öğeler kendi kendine kapanamaz
öğeler
kabul etmesini sağlar. Her zaman kapanış etiketi yaz
(
<app-drawer></app-drawer>
).
Özel öğe tepkileri
Özel bir öğe, işlem sırasında kod çalıştırmak için özel yaşam döngüsü kancaları tanımlayabilir ortaya çıktığını gösteriyor. Bunlara özel öğe tepkiler bölümüne bakın.
Ad | Şu durumda aranır: |
---|---|
constructor |
Öğenin bir örneği
oluşturulmalı veya yeni sürüme geçirilmiş olmalıdır. Başlatma için kullanışlıdır
etkinlik işleyicileri ayarlayarak veya
gölge alanı oluşturarak.
Bkz.
spesifikasyon
'nı inceleyin.
constructor sayfasında yapabileceklerinizle ilgili kısıtlamaları gözden geçirin.
|
connectedCallback |
Her seferinde öğesi DOM'ye eklenir. Örneğin, oluşturma veya oluşturmayı öğrendiniz. Genel olarak çalışmayı ertelemeye devam edecek. |
disconnectedCallback |
Öğe DOM'den her kaldırıldığında çağrılır. Şunlar için yararlıdır: çalıştırma kodundan bahsedeceğim. |
attributeChangedCallback(attrName, oldVal, newVal) |
Gözlemlenen bir özellik yapıldığında çağrılır
eklenen, kaldırılan, güncellenen veya değiştirilen Başlangıç değerleri için de çağrılır
Ayrıştırıcı tarafından bir öğe oluşturulduğunda veya
yeni sürüme geçirildi. Not: yalnızca
observedAttributes özelliğinde listelenen özellikler
bu geri aramayı alabilirsiniz.
|
adoptedCallback |
İlgili içeriği oluşturmak için kullanılan
özel öğe, yeni bir document içine taşındı (ör.
document.adoptNode(el) adlı kişi) oturum açın.
|
Tepki geri çağırmaları eşzamanlıdır. Bir kullanıcı el.setAttribute()
adlı kişiyi ararsa
kullanırsanız tarayıcı hemen attributeChangedCallback()
öğesini çağırır.
Benzer şekilde, öğeniz şu şekilde ayarlandıktan hemen sonra bir disconnectedCallback()
alırsınız:
DOM'den kaldırılmış (ör. kullanıcı el.remove()
çağrısı yapıyor).
Örnek: <app-drawer>
için özel öğe tepkileri ekleme:
class AppDrawer extends HTMLElement {
constructor() {
super(); // always call super() first in the constructor.
// ...
}
connectedCallback() {
// ...
}
disconnectedCallback() {
// ...
}
attributeChangedCallback(attrName, oldVal, newVal) {
// ...
}
}
Uygun olduğunda/gerektiğinde tepkileri tanımlayın. Öğeniz yeterince karmaşıksa
ve connectedCallback()
içinde IndexedDB için bir bağlantı açarsa
disconnectedCallback()
bölgesinde temizlik çalışması yapıldı. Ancak dikkatli olun! Yapacağınız her şeyden önce
öğesinin DOM'den kaldırılmasını sağlayabilirsiniz. Örneğin,
Kullanıcı sekmeyi kapatırsa disconnectedCallback()
hiçbir zaman çağrılmaz.
Özellikler
Özellikleri özelliklere yansıtma
HTML özelliklerinin, değerlerini DOM'ye bir
HTML özelliği. Örneğin, hidden
veya id
değerleri
JS:
div.id = 'my-id';
div.hidden = true;
değerler, yayındaki DOM'ye özellikler olarak uygulanır:
<div id="my-id" hidden>
Buna "özellikleri özellikleri" gibi bir değer kullanabilirsiniz. HTML'deki neredeyse her mülk bu işlemi gerçekleştirir. Neden? Özellikler aşağıdakiler için de yararlıdır: bir öğeyi bildirimli şekilde yapılandırma ile erişilebilirlik ve CSS gibi belirli API'ler seçicilerin çalışması için özellikler gerekir.
Bir özelliğin yansıması, öğenin DOM'sini tutmak istediğiniz her yerde yararlıdır. temsilini JavaScript durumuyla senkronize edin. Paydaşlarla iletişime geçmek bir özelliği yansıtır. Böylece, JS durumu değiştiğinde kullanıcı tanımlı stil uygulanır.
<app-drawer>
numaralı telefonumuzu hatırlayın. Bu bileşenin tüketicisi, parçayı karartmak isteyebilir
ve/veya devre dışı bırakıldığında kullanıcı etkileşimini engelleyebilir:
app-drawer[disabled] {
opacity: 0.5;
pointer-events: none;
}
JS'de disabled
özelliği değiştirildiğinde, bu özelliğin şu şekilde olmasını istiyoruz:
kullanıcının seçicisinin eşleşmesi için DOM'ye eklenir. İlgili öğe,
davranışına örnek gösterebiliriz:
get disabled() {
return this.hasAttribute('disabled');
}
set disabled(val) {
// Reflect the value of `disabled` as an attribute.
if (val) {
this.setAttribute('disabled', '');
} else {
this.removeAttribute('disabled');
}
this.toggleDrawer();
}
Özelliklerdeki değişiklikleri gözlemleme
HTML özellikleri, kullanıcıların başlangıç durumunu bildirmeleri için pratik bir yoldur:
<app-drawer open disabled></app-drawer>
Öğeler, tanımlarını kullanarak özellik değişikliklerine tepki verebilir.
attributeChangedCallback
Tarayıcı her değişiklik için bu yöntemi çağırır
observedAttributes
dizisinde listelenen özelliklere ekler.
class AppDrawer extends HTMLElement {
// ...
static get observedAttributes() {
return ['disabled', 'open'];
}
get disabled() {
return this.hasAttribute('disabled');
}
set disabled(val) {
if (val) {
this.setAttribute('disabled', '');
} else {
this.removeAttribute('disabled');
}
}
// Only called for the disabled and open attributes due to observedAttributes
attributeChangedCallback(name, oldValue, newValue) {
// When the drawer is disabled, update keyboard/screen reader behavior.
if (this.disabled) {
this.setAttribute('tabindex', '-1');
this.setAttribute('aria-disabled', 'true');
} else {
this.setAttribute('tabindex', '0');
this.setAttribute('aria-disabled', 'false');
}
// TODO: also react to the open attribute changing.
}
}
Bu örnekte, bir kullanıcı aşağıdaki işlemleri gerçekleştirdiğinde <app-drawer>
için ek özellikler ayarlıyoruz:
disabled
özelliği değiştirildi. Bunu burada yapmasak da,
bir JS özelliğiniattributeChangedCallback
özelliği ekleyin.
Öğeleri yeni sürüme geçirme
Kademeli olarak geliştirilmiş HTML
Özel öğelerin
customElements.define()
Ancak bu, bir web sitesini ziyaret etmek için
bir arada kullanabilirsiniz.
Özel öğeler, tanımları kaydedilmeden önce kullanılabilir.
Progresif geliştirme, özel öğelerden oluşan bir özelliktir. Başka bir deyişle,
sayfada bir grup <app-drawer>
öğesi beyan eder ve hiçbir zaman çağırmaz
customElements.define('app-drawer', ...)
tarihine kadar devam edebilirsiniz. Bunun nedeni,
Tarayıcı, bilinmeyen özel öğeleri nedeniyle
etiketleri kullanın. define()
çağrısı yapma ve mevcut bir
öğesine "öğe yükseltmeleri" adı verilir.
Bir etiket adının ne zaman tanımlandığını öğrenmek için
window.customElements.whenDefined()
öğesi tanımlanır.
customElements.whenDefined('app-drawer').then(() => {
console.log('app-drawer defined');
});
Örnek - bir alt öğe grubu yeni sürüme geçirilene kadar işi erteleme
<share-buttons>
<social-button type="twitter"><a href="...">Twitter</a></social-button>
<social-button type="fb"><a href="...">Facebook</a></social-button>
<social-button type="plus"><a href="...">G+</a></social-button>
</share-buttons>
// Fetch all the children of <share-buttons> that are not defined yet.
let undefinedButtons = buttons.querySelectorAll(':not(:defined)');
let promises = [...undefinedButtons].map((socialButton) => {
return customElements.whenDefined(socialButton.localName);
});
// Wait for all the social-buttons to be upgraded.
Promise.all(promises).then(() => {
// All social-button children are ready.
});
Öğe tanımlı içerik
Özel öğeler, içindeki DOM API'lerini kullanarak kendi içeriklerini yönetebilir. öğe kodudur. Tepkiler bunun için yararlıdır.
Örnek: Varsayılan HTML içeren bir öğe oluşturun:
customElements.define('x-foo-with-markup', class extends HTMLElement {
connectedCallback() {
this.innerHTML = "<b>I'm an x-foo-with-markup!</b>";
}
// ...
});
Bu etiket tanımlandığında şu sonuçlar elde edilir:
<x-foo-with-markup>
<b>I'm an x-foo-with-markup!</b>
</x-foo-with-markup>
// YAPILACAKLAR: DevSite - Satır içi etkinlik işleyicileri kullandığı için kod örneği kaldırıldı
Gölge DOM kullanan bir öğe oluşturma
Gölge DOM, bir öğenin bir yığına sahip olması, oluşturması ve stilini belirlemesi için bir yol sağlar DOM'ye eklemeniz gerekir. Hatta bazen her hafta uygulamanın tamamını tek bir etiket içinde saklar:
<!-- chat-app's implementation details are hidden away in Shadow DOM. -->
<chat-app></chat-app>
Özel bir öğede Gölge DOM kullanmak içinthis.attachShadow
constructor
:
let tmpl = document.createElement('template');
tmpl.innerHTML = `
<style>:host { ... }</style> <!-- look ma, scoped styles -->
<b>I'm in shadow dom!</b>
<slot></slot>
`;
customElements.define('x-foo-shadowdom', class extends HTMLElement {
constructor() {
super(); // always call super() first in the constructor.
// Attach a shadow root to the element.
let shadowRoot = this.attachShadow({mode: 'open'});
shadowRoot.appendChild(tmpl.content.cloneNode(true));
}
// ...
});
.
Örnek kullanım:
<x-foo-shadowdom>
<p><b>User's</b> custom text</p>
</x-foo-shadowdom>
<!-- renders as -->
<x-foo-shadowdom>
#shadow-root
<b>I'm in shadow dom!</b>
<slot></slot> <!-- slotted content appears here -->
</x-foo-shadowdom>
Kullanıcının özel metni
// YAPILACAKLAR: DevSite - Satır içi etkinlik işleyicileri kullandığı için kod örneği kaldırıldı
<template>
öğesinden öğe oluşturma
Bilmeyenler için, <template>
öğe
ayrıştırılan, sayfa yüklemede sabit olmayan ve
daha sonra çalışma zamanında etkinleştirilebilir. Web'deki başka bir temel API öğesidir
bileşen ailesi. Şablonlar, kampanya türünü tanımlamak için ideal bir yer tutucudur
yapısı hakkında daha fazla bilgi.
Örnek:
<template>
:
<template id="x-foo-from-template">
<style>
p { color: green; }
</style>
<p>I'm in Shadow DOM. My markup was stamped from a <template>.</p>
</template>
<script>
let tmpl = document.querySelector('#x-foo-from-template');
// If your code is inside of an HTML Import you'll need to change the above line to:
// let tmpl = document.currentScript.ownerDocument.querySelector('#x-foo-from-template');
customElements.define('x-foo-from-template', class extends HTMLElement {
constructor() {
super(); // always call super() first in the constructor.
let shadowRoot = this.attachShadow({mode: 'open'});
shadowRoot.appendChild(tmpl.content.cloneNode(true));
}
// ...
});
</script>
Bu birkaç kod satırı gerçekten çok etkili. Şimdiyse proje yönetiminde tarih:
- HTML'de yeni bir öğe tanımlıyoruz:
<x-foo-from-template>
- Öğenin Gölge DOM'u bir
<template>
öğesinden oluşturulur - Öğenin DOM'u, Gölge DOM'u sayesinde öğenin DOM'udur
- Öğenin dahili CSS'si, Gölge DOM sayesinde öğeyi kapsar.
Shadow DOM'deyim. İşaretlemem bir <template> şablonundan damgalandı.
// YAPILACAKLAR: DevSite - Satır içi etkinlik işleyicileri kullandığı için kod örneği kaldırıldı
Özel öğelerin stilini belirleme
Öğeniz Gölge DOM kullanarak kendi stilini tanımlasa bile kullanıcılar otomatik olarak eklenir. Bunlara "kullanıcı tanımlı stiller" denir.
<!-- user-defined styling -->
<style>
app-drawer {
display: flex;
}
panel-item {
transition: opacity 400ms ease-in-out;
opacity: 0.3;
flex: 1;
text-align: center;
border-radius: 50%;
}
panel-item:hover {
opacity: 1.0;
background: rgb(255, 0, 255);
color: white;
}
app-panel > panel-item {
padding: 5px;
list-style: none;
margin: 0 7px;
}
</style>
<app-drawer>
<panel-item>Do</panel-item>
<panel-item>Re</panel-item>
<panel-item>Mi</panel-item>
</app-drawer>
Öğenin stilleri varsa CSS spesifikliğinin nasıl çalıştığını kendinize soruyor olabilirsiniz. Gölge DOM'de tanımlanmıştır. Kesinlik açısından kullanıcı stilleri kazanır. Onlar, öğe tanımlı stili her zaman geçersiz kılar. Öğe oluşturma bir kontrol listesidir.
Kayıtlı olmayan öğelerin önceden stilini belirleme
Bir öğe yeni sürüme geçirilmeden önce şu öğeyi kullanarak CSS'de öğeyi hedefleyebilirsiniz:
:defined
gerçek olmayan sınıf. Bu, bir bileşenin önceden stilini belirlerken yararlı olur. Örneğin,
tanımlanamayan yerleşimleri gizleyerek düzeni veya diğer görsel
ve tanımlandıklarında bunların kademeli olarak
soluklaşmasını sağlayabilirsiniz.
Örnek - <app-drawer>
tanımlanmadan önce gizlenir:
app-drawer:not(:defined) {
/* Pre-style, give layout, replicate app-drawer's eventual styles, etc. */
display: inline-block;
height: 100vh;
opacity: 0;
transition: opacity 0.3s ease-in-out;
}
<app-drawer>
tanımlandıktan sonra, seçici (app-drawer:not(:defined)
)
artık eşleşmiyor.
Öğeleri genişletme
Custom Elements API'si yeni HTML öğeleri oluşturmak için yararlı olmakla birlikte aynı zamanda diğer özel öğelerin veya tarayıcının yerleşik HTML'sinin bile genişletilmesi için kullanışlıdır.
Özel öğeyi genişletme
Başka bir özel öğenin sınıf tanımı genişletilerek genişletme işlemi yapılır.
Örnek - <app-drawer>
kapsamını genişleten <fancy-app-drawer>
oluşturun:
class FancyDrawer extends AppDrawer {
constructor() {
super(); // always call super() first in the constructor. This also calls the extended class' constructor.
// ...
}
toggleDrawer() {
// Possibly different toggle implementation?
// Use ES2015 if you need to call the parent method.
// super.toggleDrawer()
}
anotherMethod() {
// ...
}
}
customElements.define('fancy-app-drawer', FancyDrawer);
Yerel HTML öğelerini genişletme
Daha özel bir <button>
oluşturmak istediğinizi varsayalım. Aynı bilgileri tekrar tekrar
<button>
ürününün işlevselliğini ve davranışını kademeli olarak artırmak daha iyi bir seçenektir.
özel öğeler kullanarak mevcut öğeyi geliştirin.
Özelleştirilmiş yerleşik öğe, tarayıcının yerleşik HTML etiketlerini kullanır. Mevcut bir süreyi uzatmanın birincil faydası öğesi, tüm özelliklerinden (DOM özellikleri, yöntemler, erişilebilirlik) elde etmektir. Progresif web (progresif web) yazmanın daha iyi bir yolu uygulaması ile mevcut HTML'yi kademeli olarak iyileştirin öğeleri arasında yer alır.
Bir öğeyi genişletmek için
doğru DOM arayüzünden kaldırın. Örneğin,
<button>
öğesinin, HTMLElement
yerine HTMLButtonElement
ayarından devralması gerekiyor.
Benzer şekilde, <img>
öğesini genişleten bir öğenin HTMLImageElement
öğesini genişletmesi gerekir.
Örnek - <button>
uzantısı uzatılıyor:
// See https://html.spec.whatwg.org/multipage/indices.html#element-interfaces
// for the list of other DOM interfaces.
class FancyButton extends HTMLButtonElement {
constructor() {
super(); // always call super() first in the constructor.
this.addEventListener('click', e => this.drawRipple(e.offsetX, e.offsetY));
}
// Material design ripple animation.
drawRipple(x, y) {
let div = document.createElement('div');
div.classList.add('ripple');
this.appendChild(div);
div.style.top = `${y - div.clientHeight/2}px`;
div.style.left = `${x - div.clientWidth/2}px`;
div.style.backgroundColor = 'currentColor';
div.classList.add('run');
div.addEventListener('transitionend', (e) => div.remove());
}
}
customElements.define('fancy-button', FancyButton, {extends: 'button'});
Yerel bir dosyayı genişletirken define()
çağrısının biraz değiştiğine dikkat edin
öğesine dokunun. Gerekli üçüncü parametre, tarayıcıya hangi etiketi
uzatılıyor. Birçok HTML etiketi aynı DOM'yi paylaştığından bu gereklidir
kullanır. <section>
, <address>
ve <em>
(diğerlerinin yanı sıra) hepsini paylaşıyor
HTMLElement
; hem <q>
hem de <blockquote>
, HTMLQuoteElement
değerini paylaşıyor; vb.
{extends: 'blockquote'}
belirtmek, tarayıcının bir
<q>
yerine <blockquote>
çorbası. HTML'ye bakın.
özellikler
sayfasını ziyaret edin.
Özelleştirilmiş bir yerleşik öğenin tüketicileri bunu birkaç şekilde kullanabilir. Şunları yapabilirler:
bunu yerel etikete is=""
özelliğini ekleyerek bildirin:
<!-- This <button> is a fancy button. -->
<button is="fancy-button" disabled>Fancy button!</button>
JavaScript'te bir örnek oluşturun:
// Custom elements overload createElement() to support the is="" attribute.
let button = document.createElement('button', {is: 'fancy-button'});
button.textContent = 'Fancy button!';
button.disabled = true;
document.body.appendChild(button);
veya new
operatörünü kullanın:
let button = new FancyButton();
button.textContent = 'Fancy button!';
button.disabled = true;
İşte <img>
kapsamını genişleten başka bir örnek.
Örnek - <img>
uzantısı uzatılıyor:
customElements.define('bigger-img', class extends Image {
// Give img default size if users don't specify.
constructor(width=50, height=50) {
super(width * 10, height * 10);
}
}, {extends: 'img'});
Kullanıcılar bu bileşeni şu şekilde beyan eder:
<!-- This <img> is a bigger img. -->
<img is="bigger-img" width="15" height="20">
veya JavaScript'te bir örnek oluşturun:
const BiggerImage = customElements.get('bigger-img');
const image = new BiggerImage(15, 20); // pass constructor values like so.
console.assert(image.width === 150);
console.assert(image.height === 200);
Çeşitli ayrıntılar
Bilinmeyen öğeler ile tanımlanmamış özel öğeler karşılaştırması
HTML esnek ve esnek bir çalışma şeklidir. Örneğin, şunu tanımlayın:
Bir sayfada <randomtagthatdoesntexist>
ve tarayıcı son derece mutlu
kabullenmek de önemlidir. Standart olmayan etiketler neden çalışır? Yanıt, HTML
spesifikasyon
izin verir. Spesifikasyon tarafından tanımlanmayan öğeler şu şekilde ayrıştırılır:
HTMLUnknownElement
Bu durum, özel öğeler için geçerli değildir. Olası özel öğeler ayrıştırılır
geçerli bir adla ("-" içeren) oluşturuldularsa HTMLElement
olarak görünürler. Siz
bunu, özel öğeleri destekleyen bir tarayıcıda kontrol edebilirsiniz. Konsolu çalıştırın:
Ctrl+Üst Karakter+J (veya Mac'te Cmd+Opt+J) tuşlarına basın ve
şu kod satırlarını kullanın:
// "tabs" is not a valid custom element name
document.createElement('tabs') instanceof HTMLUnknownElement === true
// "x-tabs" is a valid custom element name
document.createElement('x-tabs') instanceof HTMLElement === true
API referansı
customElements
global, özel boyutlarla çalışmak için yararlı yöntemler tanımlar
öğeler.
define(tagName, constructor, options)
Tarayıcıda yeni bir özel öğe tanımlar.
Örnek
customElements.define('my-app', class extends HTMLElement { ... });
customElements.define(
'fancy-button', class extends HTMLButtonElement { ... }, {extends: 'button'});
get(tagName)
Geçerli bir özel öğe etiketi adı verildiğinde, öğenin kurucusunu döndürür.
Kayıtlı öğe tanımı yoksa undefined
değerini döndürür.
Örnek
let Drawer = customElements.get('app-drawer');
let drawer = new Drawer();
whenDefined(tagName)
Özel öğe tanımlandığında çözümlenen bir Vaat döndürür. Öğe öğesi zaten tanımlıysa hemen çözün. Etiket adı uygun değilse reddedilir geçerli bir özel öğe adı olmalıdır.
Örnek
customElements.whenDefined('app-drawer').then(() => {
console.log('ready!');
});
Geçmiş ve tarayıcı desteği
Son birkaç yıldır web bileşenlerini takip ediyorsanız
Chrome 36 ve sonraki sürümlerde Custom Elements API'nin
customElements.define()
yerine document.registerElement()
. Bu kadar
standardın v0 adı verilen kullanımdan kaldırılmış bir sürümü olarak kabul edilir.
customElements.define()
yeni popülerlik ve tarayıcı tedarikçi firmaları
zaman çizelgesi oluşturur. Adı Custom Elements v1.
Eski v0 spesifikasyonuyla ilgileniyorsanız html5rocks makalesine bakın.
Tarayıcı desteği
Chrome 54 (durum), Safari 10.1 (durum) ve Firefox 63 (durum) Özel Öğeler v1. Edge, hakkında daha fazla bilgi edinin.
Özel öğeleri algılamak için mevcut olup olmadığını kontrol edin
window.customElements
:
const supportsCustomElementsV1 = 'customElements' in window;
Çoklu Dolgu
Tarayıcı desteği yaygın olarak sunulana kadar bağımsız çoklu dolgu özel öğeler v1'de kullanılabilir. Ancak, şunu kullanmanızı öneririz: webcomponents.js yükleyici en iyi şekilde yüklemenizi sağlar. Yükleyici yalnızca gerekli anket dolgularını eşzamansız olarak yüklemek için özellik algılamayı kullanır tarayıcı tarafından gerekli kılınır.
Yükleyin:
npm install --save @webcomponents/webcomponentsjs
Kullanım:
<!-- Use the custom element on the page. -->
<my-element></my-element>
<!-- Load polyfills; note that "loader" will load these async -->
<script src="node_modules/@webcomponents/webcomponentsjs/webcomponents-loader.js" defer></script>
<!-- Load a custom element definitions in `waitFor` and return a promise -->
<script type="module">
function loadScript(src) {
return new Promise(function(resolve, reject) {
const script = document.createElement('script');
script.src = src;
script.onload = resolve;
script.onerror = reject;
document.head.appendChild(script);
});
}
WebComponents.waitFor(() => {
// At this point we are guaranteed that all required polyfills have
// loaded, and can use web components APIs.
// Next, load element definitions that call `customElements.define`.
// Note: returning a promise causes the custom elements
// polyfill to wait until all definitions are loaded and then upgrade
// the document in one batch, for better performance.
return loadScript('my-element.js');
});
</script>
.
Sonuç
Özel öğeler, tarayıcıda yeni HTML etiketleri tanımlamak için bize yeni bir araç sunar ve
ve yeniden kullanılabilir bileşenler oluşturmak. Bunları diğer yeni platformla birleştirin
ve <template>
gibi temel unsurların yanı sıra büyük farkların
Web Bileşenlerinin resmi:
- Yeniden kullanılabilir bileşenler oluşturmak ve genişletmek için tarayıcılar arası (web standardı).
- Başlamak için kitaplık veya çerçeve gerekmez. Vanilla JS/HTML FTW!
- Tanıdık bir programlama modeli sunar. Bu, yalnızca DOM/CSS/HTML'dir.
- Diğer yeni web platformu özellikleriyle (Shadow DOM,
<template>
, CSS) uyumlu bir şekilde çalışır özel özellikler vb.) - Tarayıcının Geliştirici Araçları ile güçlü bir şekilde entegre edilmiştir.
- Mevcut erişilebilirlik özelliklerinden yararlanın.