Webã³ã³ããŒãã³ãã䜿çšããå©ç¹ããããã®æ©èœãããã³ãããã®äœ¿çšãéå§ããæ¹æ³ã«ã€ããŠåŠç¿ããŸã
ãWebã³ã³ããŒãã³ãïŒä»¥äžãã³ã³ããŒãã³ããšåŒã³ãŸãïŒã䜿çšãããšãéçºè ã¯ç¬èªã®HTMLèŠçŽ ãäœæã§ããŸãããã®ã¬ã€ãã§ã¯ãã³ã³ããŒãã³ãã«ã€ããŠç¥ã£ãŠããã¹ãããšããã¹ãŠåŠã³ãŸãããŸããã³ã³ããŒãã³ããšã¯äœãããããã®å©ç¹ãšã¯äœãããããŠãããã¯äœã§ã§ããŠãããããå§ããŸãã
ãã®åŸãæåã«HTMLãã³ãã¬ãŒããšã·ã£ããŠDOMã€ã³ã¿ãŒãã§ã€ã¹ã䜿çšããŠã³ã³ããŒãã³ãã®æ§ç¯ãéå§ããæ¬¡ã«ãããã¯ã«å°ãé£ã³èŸŒãã§ãã«ã¹ã¿ãã€ãºãããçµã¿èŸŒã¿èŠçŽ ãäœæããæ¹æ³ã確èªããŸãã
ã³ã³ããŒãã³ããšã¯äœã§ããïŒ
éçºè ã¯ã³ã³ããŒãã³ãã倧奜ãã§ãïŒããã§ã¯ããã¢ãžã¥ãŒã«ãèšèšãã¿ãŒã³ã®å®è£ ãæå³ããŸãïŒãããã¯ããã€ã§ãã©ãã§ã䜿çšã§ããã³ãŒãã®ãããã¯ãå®çŸ©ããããã®åªããæ¹æ³ã§ããäœå¹Žã«ãããã£ãŠããã®ã¢ã€ãã¢ãå®è¡ããããã«ãå€ããå°ãªããæåãã詊ã¿ãããã€ãè¡ãããŠããŸããã
Mozillaã®XMLãã€ã³ãã£ã³ã°èšèªãšMicrosoftã®InternetExplorer 5ã®HTMLã³ã³ããŒãã³ã仿§ã¯ãçŽ20幎åã®ãã®ã§ããæ®å¿µãªãããäž¡æ¹ã®å®è£ ã¯éåžžã«è€éã§ãä»ã®ãã©ãŠã¶ã®ã¡ãŒã«ãŒã®èå³ãåŒãããšãã§ããªãã£ããããããã«å¿ããããŸãããããã«ããããããã仿¥ãã®åéã§ç§ãã¡ãæã£ãŠãããã®ã®åºç€ãç¯ããã®ã¯åœŒãã§ããã
ReactãVueãAngularãªã©ã®JavaScriptãã¬ãŒã ã¯ãŒã¯ãåæ§ã®ã¢ãããŒããåããŸããããããæåããäž»ãªçç±ã®1ã€ã¯ãã¢ããªã±ãŒã·ã§ã³ã®äžè¬çãªããžãã¯ãããããã©ãŒã ããå¥ã®ãã©ãŒã ã«ç°¡åã«ç§»åã§ããããã€ãã®ãã³ãã¬ãŒãã«ã«ãã»ã«åã§ããããšã§ãã
ãããã®ãã¬ãŒã ã¯ãŒã¯ã¯éçºãšã¯ã¹ããªãšã³ã¹ãåäžãããŸããããã¹ãŠã«ä»£åã䌎ããŸããJSXãªã©ã®èšèªæ©èœãã³ã³ãã€ã«ããå¿ èŠããããã»ãšãã©ã®ãã¬ãŒã ã¯ãŒã¯ã¯JavaScriptãšã³ãžã³ã䜿çšããŠæœè±¡åã管çããŸããã³ãŒããã³ã³ããŒãã³ãã«åå²ããåé¡ã解決ããããã®å¥ã®ã¢ãããŒãã¯ãããŸããïŒçãã¯Webã³ã³ããŒãã³ãã§ãã
ã³ã³ããŒãã³ãã®4ã€ã®æ±
ã³ã³ããŒãã³ãã¯ãã«ã¹ã¿ã èŠçŽ ãHTMLãã³ãã¬ãŒããã·ã£ããŠDOMã®3ã€ã®APIãšããããã®åºç€ãšãªãJavaScriptã¢ãžã¥ãŒã«ïŒES6ã¢ãžã¥ãŒã«ïŒã§æ§æãããŠããŸãããããã®ã€ã³ã¿ãŒãã§ã€ã¹ã«ãã£ãŠæäŸãããããŒã«ã䜿çšããŠããã€ãã£ãã®å¯Ÿå¿ç©ã®ããã«åäœããã«ã¹ã¿ã HTMLèŠçŽ ãäœæã§ããŸãã
ã³ã³ããŒãã³ãã¯ãéåžžã®HTMLèŠçŽ ãšåãæ¹æ³ã§äœ¿çšãããŸãããããã¯ã屿§ã䜿çšããŠã«ã¹ã¿ãã€ãºããããJavaScriptã䜿çšããŠååŸããããCSSã䜿çšããŠã¹ã¿ã€ã«ãèšå®ãããã§ããŸããäž»ãªããšã¯ãããããååšããããšããã©ãŠã¶ã«éç¥ããããšã§ãã
ããã«ãããã³ã³ããŒãã³ããä»ã®ãã¬ãŒã ã¯ãŒã¯ãã©ã€ãã©ãªãšçžäºäœçšã§ããããã«ãªããŸããéåžžã®èŠçŽ ãšåãéä¿¡ã¡ã«ããºã ã䜿çšããããšã«ãããæ¢åã®ãã¬ãŒã ã¯ãŒã¯ã ãã§ãªããå°æ¥ç»å ŽããããŒã«ã§ã䜿çšã§ããŸãã
ã³ã³ããŒãã³ããWebæšæºã«æºæ ããŠããããšã«ã泚æããŠãã ããããŠã§ãã¯åŸæ¹äºææ§ã®ã¢ã€ãã¢ã«åºã¥ããŠããŸããããã¯ã仿¥äœæãããã³ã³ããŒãã³ããé·æéã«ããã£ãŠããŸãæ©èœããããšãæå³ããŸãã
ããããã®ä»æ§ãåå¥ã«èŠãŠãããŸãããã
1.ã«ã¹ã¿ã èŠçŽ
äž»ãªæ©èœïŒ
- èŠçŽ ã®åäœã®å®çŸ©
- 屿§ã®å€æŽãžã®å¯Ÿå¿
- æ¢åã®èŠçŽ ãæ¡åŒµãã
å€ãã®å Žåã人ã ãã³ã³ããŒãã³ãã«ã€ããŠè©±ããšãããããã¯ã«ã¹ã¿ã èŠçŽ ã®ã€ã³ã¿ãŒãã§ãŒã¹ãæå³ããŸãã
ãã®APIã䜿çšãããšã远å ãæŽæ°ãããã³åé€ããããšãã®åäœãå®çŸ©ããããšã«ãããèŠçŽ ãæ¡åŒµã§ããŸãã
class ExampleElement extends HTMLElement {
static get observedAttributes() {
return [...]
}
attributeChangedCallback(name, oldValue, newValue) {}
connectedCallback() {}
}
customElements.define('example-element', ExampleElement)
åã«ã¹ã¿ã èŠçŽ ã¯åæ§ã®æ§é ãæã£ãŠããŸããããã¯ãæ¢åã®HTMLElementsã¯ã©ã¹ã®æ©èœãæ¡åŒµããŸãã
ã«ã¹ã¿ã èŠçŽ å ã«ã¯ãèŠçŽ ãžã®ç¹å®ã®å€æŽã®åŠçãæ åœãããªã¢ã¯ã·ã§ã³ãšåŒã°ããããã€ãã®ã¡ãœããããããŸããããšãã°ãconnectedCallbackã¯ãã¢ã€ãã ãããŒãžã«è¿œå ããããšãã«åŒã³åºãããŸããããã¯ããã¬ãŒã ã¯ãŒã¯ã§äœ¿çšãããã©ã€ããµã€ã¯ã«ã¹ããŒãžïŒReactã®componentDidMountãVueã«ããŠã³ãïŒã«äŒŒãŠããŸãã
èŠçŽ ã®å±æ§ã倿Žãããšããã®åäœã倿ŽãããŸããæŽæ°ãçºçãããšã倿Žã«é¢ããæ å ±ãå«ãattributeChangedCallbackãåŒã³åºãããŸããããã¯ãobservedAttributesã«ãã£ãŠè¿ãããé åã§æå®ããã屿§ã«å¯ŸããŠã®ã¿çºçããŸãã
èŠçŽ ã¯ããã©ãŠã¶ã䜿çšããåã«å®çŸ©ããå¿ èŠããããŸãããdefineãã¡ãœããã¯ãã¿ã°ã®ååãšãã®ã¯ã©ã¹ã®2ã€ã®åŒæ°ãåããŸããæ¢åããã³å°æ¥ã®ãã€ãã£ãèŠçŽ ãšã®ç«¶åãé¿ããããã«ããã¹ãŠã®ã¿ã°ã«ã¯ã-ãæåãå«ããå¿ èŠããããŸãã
<example-element>Content</example-element>
ãã®èŠçŽ ã¯ãéåžžã®HTMLã¿ã°ãšåãããã«äœ¿çšã§ããŸãããã®ãããªèŠçŽ ãèŠã€ãããšããã©ãŠã¶ã¯ãã®åäœãæå®ãããã¯ã©ã¹ã«é¢é£ä»ããŸãããã®ããã»ã¹ã¯ãã¢ããã°ã¬ãŒãããšåŒã°ããŸãã
ã¢ã€ãã ã«ã¯ããèªåŸåããšãã«ã¹ã¿ãã€ãºãããçµã¿èŸŒã¿åãã®2çš®é¡ããããŸãããããŸã§ãã¹ã¿ã³ãã¢ãã³ã¢ã€ãã ã«ã€ããŠèŠãŠããŸããããããã¯ãæ¢åã®HTMLèŠçŽ ã«é¢é£ããªãèŠçŽ ã§ããdivã¿ã°ãspanã¿ã°ã®ããã«ãç¹å®ã®æå³ã¯ãããŸããã
ã«ã¹ã¿ã ã€ã³ã©ã€ã³èŠçŽ ã¯ããã®ååã瀺ãããã«ãæ¢åã®HTMLèŠçŽ ã®æ©èœãæ¡åŒµããŸãããããã¯ãããã®èŠçŽ ã®ã»ãã³ãã£ãã¯åäœãç¶æ¿ããããã倿Žããããšãã§ããŸããããšãã°ããinputãèŠçŽ ãã«ã¹ã¿ãã€ãºãããŠããå Žåã§ããéä¿¡æã«å ¥åãã£ãŒã«ããšãã©ãŒã ã®äžéšã®ãŸãŸã«ãªããŸãã
class CustomInput extends HTMLInputElement {}
customElements.define('custom-input', CustomInput, { extends: 'input' })
ã«ã¹ã¿ã ã€ã³ã©ã€ã³èŠçŽ ã¯ã©ã¹ã¯ãã«ã¹ã¿ã èŠçŽ ã¯ã©ã¹ãæ¡åŒµããŸããã€ã³ã©ã€ã³èŠçŽ ãå®çŸ©ããå Žåãå±éå¯èœãªèŠçŽ ã¯3çªç®ã®åŒæ°ãšããŠæž¡ãããŸãã
<input is="custom-input" />
ã¿ã°ã®äœ¿ãæ¹ãå°ãç°ãªããŸããæ°ããã¿ã°ã®ä»£ããã«ãæ¢åã®ã¿ã°ã䜿çšãããç¹å¥ãªãisãæ¡åŒµå±æ§ãæå®ãããŸãããã©ãŠã¶ããã®å±æ§ãæ€åºãããšãã«ã¹ã¿ã èŠçŽ ãåŠçããŠããããšãèªèããããã«å¿ããŠæŽæ°ããŸãã
ã¹ã¿ã³ãã¢ãã³èŠçŽ ã¯ã»ãšãã©ã®ææ°ã®ãã©ãŠã¶ã§ãµããŒããããŠããŸãããã«ã¹ã¿ã ã€ã³ã©ã€ã³èŠçŽ ã¯ChromeãšFirefoxã§ã®ã¿ãµããŒããããŠããŸãããããããµããŒãããŠããªããã©ãŠã¶ã§äœ¿çšãããšãåŸè ã¯éåžžã®HTMLèŠçŽ ã®ããã«æ±ããããããæŠããŠããããã®ãã©ãŠã¶ã§ãå®å šã«äœ¿çšã§ããŸãã
2.HTMLãã³ãã¬ãŒã
- æ¢è£œã®æ§é ã®äœæ
- é話åã®ããŒãžã«ã¯è¡šç€ºãããŸãã
- HTMLãCSSãJSãå«ãŸããŠããŸã
ãããŸã§ãã¯ã©ã€ã¢ã³ãåŽã®ãã³ãã¬ãŒãäœæã§ã¯ãJavaScriptã§æååãé£çµãããããã³ãã«ããŒãªã©ã®ã©ã€ãã©ãªã䜿çšããŠã«ã¹ã¿ã ããŒã¯ã¢ããã®ãããã¯ãè§£æããŠããŸãããæè¿ã仿§ã«ã¯ã䜿çšããããã®ãäœã§ãå«ããããšãã§ããããã³ãã¬ãŒããã¿ã°ããããŸãã
<template id="tweet">
<div class="tweet">
<span class="message"></span>
Written by @
<span class="username"></span>
</div>
</template>
ããèªäœã§ã¯ãããŒãžã«åœ±é¿ãäžããããšã¯ãããŸããããšã³ãžã³ã«ãã£ãŠè§£æãããããªãœãŒã¹ïŒãªãŒãã£ãªããããªïŒã®èŠæ±ã¯éä¿¡ãããŸãããJavaScriptã¯ããã«ã¢ã¯ã»ã¹ã§ããããã©ãŠã¶ãŒã®å Žåã¯ç©ºã®èŠçŽ ã§ãã
const template = document.getElementById('tweet')
const node = document.importNode(template.content, true)
document.body.append(node)
ãŸããããã³ãã¬ãŒããèŠçŽ ãååŸããŸããimportNodeã¡ãœããã¯ãã®ã³ã³ãã³ãã®ã³ããŒãäœæããŸãã2çªç®ã®åŒæ°ïŒtrueïŒã¯ãã£ãŒãã³ããŒãæå³ããŸããæåŸã«ãä»ã®èŠçŽ ãšåãããã«ããŒãžã«è¿œå ããŸãã
ãã³ãã¬ãŒãã«ã¯ãCSSãJavaScriptãªã©ãéåžžã®HTMLã«å«ããããšãã§ãããã¹ãŠã®ãã®ãå«ããããšãã§ããŸããèŠçŽ ãããŒãžã«è¿œå ããããšãã¹ã¿ã€ã«ããã®ããŒãžã«é©çšãããã¹ã¯ãªãããèµ·åãããŸããã¹ã¿ã€ã«ãšã¹ã¯ãªããã¯ã°ããŒãã«ã§ããããšã«æ³šæããŠãã ãããã€ãŸããã¹ã¯ãªããã§äœ¿çšãããä»ã®ã¹ã¿ã€ã«ãšå€ãäžæžãããå¯èœæ§ããããŸãã
ãã³ãã¬ãŒãã¯ããã«éå®ãããŸãããã³ã³ããŒãã³ãã®ä»ã®éšåãç¹ã«ã·ã£ããŠDOMã§äœ¿çšãããšããã¹ãŠã®æ å ãçŸããŸãã
3.ã·ã£ããŠDOM
- ã¹ã¿ã€ã«ã®ç«¶åãåé¿ããŸã
- ïŒã¯ã©ã¹ãªã©ã®ïŒååãæãä»ãã®ãç°¡åã«ãªããŸã
- å®è£ ããžãã¯ã®ã«ãã»ã«å
ããã¥ã¡ã³ããªããžã§ã¯ãã¢ãã«ïŒDOMïŒã¯ããã©ãŠã¶ãããŒãžã®æ§é ãè§£éããæ¹æ³ã§ããããŒã¯ã¢ãããèªã¿åãããšã«ããããã©ãŠã¶ã¯ã©ã®èŠçŽ ã«ã©ã®ã³ã³ãã³ããå«ãŸããŠãããã倿ããããã«åºã¥ããŠãããŒãžã«äœã衚瀺ããããæ±ºå®ããŸããããšãã°ãdocument.getElemetByIdïŒïŒã䜿çšããå Žåããã©ãŠã¶ã¯DOMã«ã¢ã¯ã»ã¹ããŠå¿ èŠãªèŠçŽ ãèŠã€ããŸãã
ããŒãžã¬ã€ã¢ãŠãã®å Žåãããã¯åé¡ãããŸããããèŠçŽ å ã«é ãããŠãã詳现ã«ã€ããŠã¯ã©ãã§ãããããããšãã°ãããŒãžã¯ãvideoãèŠçŽ ã«å«ãŸããã€ã³ã¿ãŒãã§ã€ã¹ãæ°ã«ããå¿ èŠã¯ãããŸãããããã§ã·ã£ããŠDOMã圹ã«ç«ã¡ãŸãã
<div id="shadow-root"></div>
<script>
const host = document.getElementById('shadow-root')
const shadow = host.attachShadow({ mode: 'open' })
</script>
ã·ã£ããŠDOMã¯ãèŠçŽ ã«é©çšããããšäœæãããŸããéåžžã®ïŒãã©ã€ããïŒDOMãšåãããã«ãä»»æã®ã³ã³ãã³ããã·ã£ããŠDOMã«è¿œå ã§ããŸããã·ã£ããŠDOMã¯ãå€éšã§çºçããããšã®åœ±é¿ãåããŸãããããã®å€ããã¬ãŒã³DOMãã·ã£ããŠã«çŽæ¥ã¢ã¯ã»ã¹ã§ããŸãããã€ãŸããã·ã£ããŠDOMã§ã¯ãä»»æã®ã¯ã©ã¹åãã¹ã¿ã€ã«ãããã³ã¹ã¯ãªããã䜿çšã§ããç«¶åã®å¯èœæ§ã«ã€ããŠå¿é ããå¿ èŠã¯ãããŸããã
æè¯ã®çµæã¯ãã«ã¹ã¿ã èŠçŽ ãšçµã¿åãããŠã·ã£ããŠDOMã䜿çšããŠåŸãããŸããã·ã£ããŠDOMã®ãããã§ãã³ã³ããŒãã³ããåå©çšããããšãããã®ã¹ã¿ã€ã«ãšæ§é ã¯ããŒãžäžã®ä»ã®èŠçŽ ã«ãŸã£ãã圱é¿ãäžããŸããã
ESããã³HTMLã¢ãžã¥ãŒã«
- å¿ èŠã«å¿ããŠè¿œå
- äºåçæã¯å¿ èŠãããŸãã
- ãã¹ãŠã1ãæã«ä¿åãããŸã
以åã®3ã€ã®ä»æ§ã¯éçºã«ãããŠé·ãéã®ããæ©ãã§ããŸããããããããã©ã®ããã«ããã±ãŒãžåããŠåå©çšãããã«ã€ããŠã¯ãäŸç¶ãšããŠæ¿ããè°è«ã®å¯Ÿè±¡ãšãªã£ãŠããŸãã
HTML Imports仿§ã¯ãHTMLããã¥ã¡ã³ããããã³CSSãšJavaScriptããšã¯ã¹ããŒãããã³ã€ã³ããŒãããæ¹æ³ãå®çŸ©ããŸããããã«ãããã«ã¹ã¿ã èŠçŽ ããã³ãã¬ãŒãããã³ã·ã£ããŠDOMãšãšãã«å¥ã®å Žæã«é 眮ããå¿ èŠã«å¿ããŠäœ¿çšã§ããããã«ãªããŸãã
ãã ããFirefoxã¯ãã®ä»æ§ããã©ãŠã¶ã«å®è£ ããããšãæåŠããJavaScriptã¢ãžã¥ãŒã«ã«åºã¥ããŠç°ãªãæ¹æ³ãæäŸããŸããã
export class ExampleElement external HTMLElement {}
import { ExampleElement } from 'ExampleElement.js'
ã¢ãžã¥ãŒã«ã«ã¯ãããã©ã«ãã§ç¬èªã®ååããããŸãããããã®ã³ã³ãã³ãã¯ã°ããŒãã«ã§ã¯ãããŸããããšã¯ã¹ããŒãããã倿°ã颿°ãããã³ã¯ã©ã¹ã¯ããã€ã§ãã©ãã§ãã€ã³ããŒãã§ããããŒã«ã«ãªãœãŒã¹ãšããŠäœ¿çšã§ããŸãã
ããã¯ã³ã³ããŒãã³ãã«æé©ã§ãããã³ãã¬ãŒããšã·ã£ããŠDOMãå«ãã«ã¹ã¿ã èŠçŽ ã¯ããããã¡ã€ã«ãããšã¯ã¹ããŒãããŠå¥ã®ãã¡ã€ã«ã§äœ¿çšã§ããŸãã
import { ExampleElement } from 'ExampleElement.html'
Microsoftã¯ãJavaScriptã¢ãžã¥ãŒã«ä»æ§ãHTMLãšã¯ã¹ããŒã/ã€ã³ããŒãã§æ¡åŒµããææ¡ãæåºããŸãããããã«ããã宣èšçããã³ã»ãã³ãã£ãã¯HTMLã䜿çšããŠã³ã³ããŒãã³ããäœæã§ããŸãããã®æ©èœã¯ãŸããªãChromeãšEdgeã«å°å ¥ãããŸãã
ç¬èªã®ã³ã³ããŒãã³ããäœæãã
ã³ã³ããŒãã³ãã«ã€ããŠã¯è€éã«æããããšããããããããŸãããåçŽãªã³ã³ããŒãã³ããäœæããŠäœ¿çšããã«ã¯ãæ°è¡ã®ã³ãŒãããå¿ èŠãããŸãããããã€ãã®äŸãèŠãŠã¿ãŸãããã
ã³ã³ããŒãã³ãã䜿çšãããšãHTMLãã³ãã¬ãŒãããã³ã·ã£ããŠDOMã€ã³ã¿ãŒãã§ã€ã¹ã䜿çšããŠãŠãŒã¶ãŒã³ã¡ã³ãã衚瀺ã§ããŸãã
HTMLãã³ãã¬ãŒããšã·ã£ããŠDOMã䜿çšããŠãŠãŒã¶ãŒã³ã¡ã³ãã衚瀺ããã³ã³ããŒãã³ããäœæããŸãããã
1.ãã³ãã¬ãŒãã®äœæ
ã³ã³ããŒãã³ãã«ã¯ãããŒã¯ã¢ãããçæããåã«ã³ããŒãããã³ãã¬ãŒããå¿ èŠã§ãããã³ãã¬ãŒãã¯ããŒãžã®ã©ãã«ã§ãé 眮ã§ããã«ã¹ã¿ã èŠçŽ ã¯ã©ã¹ã¯IDãä»ããŠãã³ãã¬ãŒãã«ã¢ã¯ã»ã¹ã§ããŸãã
ããã³ãã¬ãŒããèŠçŽ ãããŒãžã«è¿œå ããŸãããã®èŠçŽ ã§å®çŸ©ãããã¹ã¿ã€ã«ã¯ããã®èŠçŽ ã«ã®ã¿åœ±é¿ããŸãã
<template id="user-comment-template">
<style>
...
</style>
</template>
2.ããŒã¯ã¢ããã®è¿œå
ã¹ã¿ã€ã«ã«å ããŠãã³ã³ããŒãã³ãã«ã¯ã¬ã€ã¢ãŠãïŒæ§é ïŒãå«ããããšãã§ããŸãããã®ç®çã®ããã«ããdivãèŠçŽ ã䜿çšãããŸãã
åçã³ã³ãã³ãã¯ã¹ããããééããŸããé©åãªãååã屿§ã䜿çšããŠãã¢ãã¿ãŒãååãããã³ãŠãŒã¶ãŒã¡ãã»ãŒãžçšã®ã¹ãããã远å ããŸãã
<div class="container">
<div class="avatar-container">
<slot name="avatar"></slot>
</div>
<div class="comment">
<slot name="username"></slot>
<slot name="comment"></slot>
</div>
</div>
ããã©ã«ãã®ã¹ãããã³ã³ãã³ã
ã¹ãããã«æž¡ãããæ å ±ããªãå Žåãããã©ã«ãã®ã³ã³ãã³ãã衚瀺ãããŸããã¹ãããã«
æž¡ãããããŒã¿ã¯ããã³ãã¬ãŒãã®ããŒã¿ãäžæžãããŸããã¹ãããã«æ å ±ãæž¡ãããªãå Žåãããã©ã«ãã®ã³ã³ãã³ãã衚瀺ãããŸãã
ãã®å ŽåããŠãŒã¶ãŒåã転éãããªãã£ãå Žåã¯ã代ããã«ãååãªãããšããã¡ãã»ãŒãžã衚瀺ãããŸãã
<slot name="username">
<span class="unknown">No name</span>
</slot>
3.ã¯ã©ã¹ã®äœæ
ã«ã¹ã¿ã èŠçŽ ã®äœæã¯ãHTMLElementã¯ã©ã¹ãæ¡åŒµããããšããå§ãŸããŸããã»ããã¢ããããã»ã¹ã®äžéšã¯ãèŠçŽ ã®ã³ã³ãã³ããã¬ã³ããªã³ã°ããããã®ã·ã£ããŠã«ãŒããäœæããããšã§ããæ¬¡ã®æ®µéã§ã¢ã¯ã»ã¹ã§ããããã«éããŸãã
æåŸã«ãæ°ããUserCommentã¯ã©ã¹ã«ã€ããŠãã©ãŠã¶ã«éç¥ããŸãã
class UserComment extends HTMLElement {
constructor() {
super()
this.attachShadow({ mode: 'open' })
}
}
customElements.define('user-comment', UserComment)
4.ã·ã£ããŠã³ã³ãã³ãã®é©çš
ãã©ãŠã¶ããuser-commentãèŠçŽ ãæ€åºãããšãã·ã£ããŠã«ãŒãããŒãã調ã¹ãŠã³ã³ãã³ããååŸããŸãã2çªç®ã®åŒæ°ã¯ãæåã®ã¬ã€ã€ãŒïŒæäžäœã®èŠçŽ ïŒã ãã§ãªãããã¹ãŠã®ã³ã³ãã³ããã³ããŒããããã«ãã©ãŠã¶ãŒã«æç€ºããŸãã
ã·ã£ããŠã«ãŒãããŒãã«ããŒã¯ã¢ããã远å ãããšãã³ã³ããŒãã³ãã®å€èгãããã«æŽæ°ãããŸãã
connectedCallback() {
const template = document.getElementById('user-comment-template')
const node = document.importNode(template.content, true)
this.shadowRoot.append(node)
}
5.ã³ã³ããŒãã³ãã®äœ¿çš
ããã§ãã³ã³ããŒãã³ãã䜿çšããæºåãæŽããŸããããuser-commentãã¿ã°ã远å ããå¿ èŠãªæ å ±ãæž¡ããŸãã
ãã¹ãŠã®ã¹ãããã«ååããããããã¹ãããã®å€éšã«æž¡ããããã®ã¯ãã¹ãŠç¡èŠãããŸããã¹ã¿ã€ãªã³ã°ãå«ããã¹ãããå ã®ãã¹ãŠãæž¡ããããšããã«æ£ç¢ºã«ã³ããŒãããŸãã
<user-comment>
<img alt="" slot="avatar" src="avatar.png" />
<span slot="username">Matt Crouch</span>
<div slot="comment">This is an example of a comment</div>
</user-comment>
æ¡åŒµãµã³ãã«ã³ãŒãïŒ
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Web Components Example</title>
<style>
body {
display: grid;
place-items: center;
}
img {
width: 80px;
border-radius: 4px;
}
</style>
</head>
<body>
<template id="user-comment-template">
<div class="container">
<div class="avatar-container">
<slot name="avatar">
<slot class="unknown"></slot>
</slot>
</div>
<div class="comment">
<slot name="username">No name</slot>
<slot name="comment"></slot>
</div>
</div>
<style>
.container {
width: 320px;
clear: both;
margin-bottom: 1rem;
}
.avatar-container {
float: left;
margin-right: 1rem;
}
.comment {
height: 80px;
display: flex;
flex-direction: column;
justify-content: center;
}
.unknown {
display: block;
width: 80px;
height: 80px;
border-radius: 4px;
background: #ccc;
}
</style>
</template>
<user-comment>
<img alt="" slot="avatar" src="avatar1.jpg" />
<span slot="username">Matt Crouch</span>
<div slot="comment">Fisrt comment</div>
</user-comment>
<user-comment>
<img alt="" slot="avatar" src="avatar2.jpg" />
<!-- no username -->
<div slot="comment">Second comment</div>
</user-comment>
<user-comment>
<!-- no avatar -->
<span slot="username">John Smith</span>
<div slot="comment">Second comment</div>
</user-comment>
<script>
class UserComment extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: "open" });
}
connectedCallback() {
const template = document.getElementById("user-comment-template");
const node = document.importNode(template.content, true);
this.shadowRoot.append(node);
}
}
customElements.define("user-comment", UserComment);
</script>
</body>
</html>
ã«ã¹ã¿ã ã€ã³ã©ã€ã³èŠçŽ ã®äœæ
åè¿°ã®ããã«ãã«ã¹ã¿ã èŠçŽ ã¯æ¢åã®èŠçŽ ãæ¡åŒµã§ããŸããããã«ããããããŒããŒã«ãã£ãŠæäŸãããèŠçŽ ã®ããã©ã«ãã®åäœãç¶æããããããæéãç¯çŽãããŸãããã®ã»ã¯ã·ã§ã³ã§ã¯ããtimeãèŠçŽ ãæ¡åŒµããæ¹æ³ãèŠãŠãããŸãã
1.ã¯ã©ã¹ã®äœæ
ã¹ã¿ã³ãã¢ãã³èŠçŽ ãªã©ã®çµã¿èŸŒã¿èŠçŽ ã¯ãã¯ã©ã¹ãæ¡åŒµããããšè¡šç€ºãããŸãããäžè¬çãªã¯ã©ã¹ãHTMLElementãã®ä»£ããã«ãç¹å®ã®ã¯ã©ã¹ãæ¡åŒµããŸãã
ãã®å Žåããã®ã¯ã©ã¹ã¯HTMLTimeElementã§ããããã¯ãtimeãèŠçŽ ã«ãã£ãŠäœ¿çšãããã¯ã©ã¹ã§ããããã«ã¯ãããŒã¿åœ¢åŒãªã©ããdatetimeã屿§ã«é¢é£ããåäœãå«ãŸããŸãã
class RelativeTime extends HTMLTimeElement {}
2.èŠçŽ ã®å®çŸ©
èŠçŽ ã¯ããdefineãã¡ãœããã䜿çšããŠãã©ãŠã¶ã«ãã£ãŠç»é²ãããŸãããã ããã¹ã¿ã³ãã¢ãã³èŠçŽ ãšã¯ç°ãªããã€ã³ã©ã€ã³èŠçŽ ãç»é²ããå Žåããdefineãã¡ãœããã«ã¯3çªç®ã®åŒæ°ïŒèšå®ã®ãããªããžã§ã¯ãïŒãæž¡ãå¿ èŠããããŸãã
ãªããžã§ã¯ãã«ã¯ãã«ã¹ã¿ã èŠçŽ ã®å€ãæã€1ã€ã®ããŒãå«ãŸããŸããã¿ã°ã®ååãåããŸãããã®ãããªããŒããªãå ŽåãäŸå€ãã¹ããŒãããŸãã
customElements.define('relative-time', RelativeTime, { extends: 'time' })
3.æéãèšå®ãã
1ããŒãžã«è€æ°ã®ã³ã³ããŒãã³ããå«ããããšãã§ãããããã³ã³ããŒãã³ãã¯èŠçŽ ã®å€ãèšå®ããããã®ã¡ãœãããæäŸããå¿ èŠããããŸãããã®ã¡ãœããå ã§ãã³ã³ããŒãã³ãã¯æéå€ããtimeagoãã©ã€ãã©ãªã«æž¡ãããã®ã©ã€ãã©ãªããè¿ãããå€ãã¢ã€ãã å€ãšããŠèšå®ããŸãïŒããŒãããžãŒã§ç³ãèš³ãããŸããïŒã
æåŸã«ããŠãŒã¶ãŒããããŒã§èšå®ãããå€ã確èªã§ããããã«ãtitle屿§ãèšå®ããŸãã
setTime() {
this.innerHTML = timeago().format(this.getAttribute('datetime'))
this.setAttribute('title', this.getAttribute('datetime'))
}
4.æ¥ç¶ã®æŽæ°
ã³ã³ããŒãã³ãã¯ãããŒãžã«è¡šç€ºãããçŽåŸã«ã¡ãœããã䜿çšã§ããŸããã€ã³ã©ã€ã³ã³ã³ããŒãã³ãã«ã¯ã·ã£ããŠDOMããªããããã³ã³ã¹ãã©ã¯ã¿ãŒã¯å¿ èŠãããŸããã
connectedCAllback() {
this.setTime()
}
5.屿§ã®å€æŽã远跡ãã
ããã°ã©ã ã§æéãæŽæ°ãããšãã³ã³ããŒãã³ãã¯å¿çããŸããã圌ã¯ããdatetimeã屿§ã®å€æŽãç£èŠããå¿ èŠãããããšãç¥ããŸããã
ç£èŠå¯Ÿè±¡ã®å±æ§ãå®çŸ©ããããšã屿§ã倿Žããããã³ã«attributeChangedCallbackãåŒã³åºãããŸãã
static get observedAttributes() {
return ['datetime']
}
attributeChangedCallback() {
this.setTime()
}
6.ããŒãžã«è¿œå ãã
ç§ãã¡ã®èŠçŽ ã¯ãã€ãã£ãèŠçŽ ã®æ¡åŒµã§ããããããã®å®è£ ã¯å°ãç°ãªããŸããããã䜿çšããã«ã¯ãç¹å¥ãªå±æ§ãisãã䜿çšããŠããŒãžã«ã¿ã°ãtimeãã远å ããŸãããã®å±æ§ã®å€ã¯ãç»é²æã«å®çŸ©ãããçµã¿èŸŒã¿èŠçŽ ã®ååã§ããã³ã³ããŒãã³ãããµããŒãããŠããªããã©ãŠã¶ã¯ããã©ãŒã«ããã¯ã³ã³ãã³ããã¬ã³ããªã³ã°ããŸãã
<time is="relative-time" datetime="2020-09-20T12:00:00+0000">
20 2020 . 12:00
</time>
æ¡åŒµãµã³ãã«ã³ãŒãïŒ
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Web Components Another Example</title>
<!-- timeago.js -->
<script
src="https://cdnjs.cloudflare.com/ajax/libs/timeago.js/4.0.2/timeago.min.js"
integrity="sha512-SVDh1zH5N9ChofSlNAK43lcNS7lWze6DTVx1JCXH1Tmno+0/1jMpdbR8YDgDUfcUrPp1xyE53G42GFrcM0CMVg=="
crossorigin="anonymous"
></script>
<style>
body {
display: flex;
flex-direction: column;
align-items: center;
}
input,
button {
margin-bottom: 0.5rem;
}
time {
font-size: 2rem;
}
</style>
</head>
<body>
<input type="text" placeholder="2020-10-20" value="2020-08-19" />
<button>Set Time</button>
<time is="relative-time" datetime="2020-09-19">
19 2020 .
</time>
<script>
class RelativeTime extends HTMLTimeElement {
setTime() {
this.innerHTML = timeago.format(this.getAttribute("datetime"));
this.setAttribute("title", this.getAttribute("datetime"));
}
connectedCallback() {
this.setTime();
}
static get observedAttributes() {
return ["datetime"];
}
attributeChangedCallback() {
this.setTime();
}
}
customElements.define("relative-time", RelativeTime, { extends: "time" });
const button = document.querySelector("button");
const input = document.querySelector("input");
const time = document.querySelector("time");
button.onclick = () => {
const { value } = input;
time.setAttribute("datetime", value);
};
</script>
</body>
</html>
Webã³ã³ããŒãã³ããšã¯äœãããããã®ç®çãããã³ãããã®äœ¿ç𿹿³ã«ã€ããŠã®åºæ¬çãªçè§£ã«åœ¹ç«ã€ããšãé¡ã£ãŠããŸãã