본문으로 건너뛰기
  1. Posts/

Javascript Custom HTMLElement 2

·3 분· loading · loading ·
Yna
Techtopic CSS Html Javascript
InnoFactory
작성자
InnoFactory
스마트팩토리, 산업자동화, Digital Transformation, 디지털팩토리, PLM, ALM, Digital Manufacturing, Visualization, 3D CAD, Digital Twin, Big Data, IIoT 솔루션 전문업체
작성자
Yeongkyun Na
Developer of Innofactory.

Custom HTMLElement
#

이번 포스팅에선 Custom HTMLElement의 스타일을 변경하는 방법과 만든 Custom HTMLElement를 사용한 예제를 간략하게 포스팅 하겠습니다.

CSS 적용하기
#

const styleText = `
div {
    border : 1px solid;
    margin: 15px;
    width : 200px;
    height: 240px;
}`;
class CustomTag extends HTMLElement {
    constructor() {
        
	... 중략 ...
    
		// 스타일 적용방법 1
        const styleSheet = new CSSStyleSheet();
        styleSheet.replaceSync(styleText);
        shadowRoot.adoptedStyleSheets= [styleSheet];
        // 스타일 적용방법 2
        shadowRoot.innerHTML = `
        <style>
            div > p {
                font-weight : bold;                
            }
        </style>`

위와 같은 방법으로 Custom Element에 CSS를 적용할 수 있습니다.

Custom HTMLElement 예제
#

Custom HTMLElement 는 개발자가 HTMLElement를 상속받아 필요한 기능을 정의하여, 재사용할 수 있는 Component화를 가능하게 합니다.

Component 만들기 1
#

Card Component를 예를 들어서 만들어 보겠습니다.

const styleText = `
div {
    border : 1px solid;
    margin: 15px;
    width : 200px;
    height: 240px;
}
.default-card-content {
    width: 200px;
    height: 185px;
}
`;
class CustomTag extends HTMLElement {

    constructor() {
        super();
 		// Create a shadow root.
        const shadowRoot = this.attachShadow({ mode: "open" });

        // 예제를 위해 태그 변경
        const div = document.createElement("div");
        const paragraph = document.createElement("p");
        const cardTitle = document.createElement("slot");
        cardTitle.name = "card-title";
        paragraph.appendChild(cardTitle);
 		div.appendChild(paragraph);
        
        const cardContent = document.createElement("slot");
        cardContent.name = "card-content";
        cardContent.classList.add("fit");
        // 이미지를 지정하지 않으면 기본 이미지가 표시됩니다.
        const cardContentDefault = document.createElement('img');
        cardContentDefault.src = "./noimage.png";
        cardContentDefault.alt = "no image";
        cardContentDefault.classList.add("default-card-content");
        
        cardContent.appendChild(cardContentDefault);
        div.appendChild(cardContent);
        
        // 스타일 변경 1
        const styleSheet = new CSSStyleSheet();
        styleSheet.replaceSync(styleText);
        shadowRoot.adoptedStyleSheets= [styleSheet];
        // 스타일 변경 2
        shadowRoot.innerHTML = `
        <style>
            div > p {
                font-weight : bold;                
            }
        </style>`
        shadowRoot.appendChild(div);
    }    
}
customElements.define("my-custom-tag", CustomTag);

document객체로 html 요소들을 생성하여 카드 component의 모양을 만들었습니다.

Component 만들기 2
#

위의 코드는 가독성이 떨어지는 것 같습니다. 친숙하고 보기 좋은 HTML 코드로 수정하겠습니다.

const styleText = `
div {
    border : 1px solid;
    margin: 15px;
    width : 200px;
    height: 240px;
}
.default-card-content {
    width: 200px;
    height: 185px;
}
`;
const template = `
    <div>
        <p>
            <slot name="card-title"></slot>
        </p>
        <slot name="card-content" class="fit">
            <img alt="no image" src="./noimage.png" class="default-card-content"/>
        </slot>
    </div>
`;
class CustomTag extends HTMLElement {

    constructor() {

        super();

 		// Create a shadow root.
        const shadowRoot = this.attachShadow({ mode: "open" });
        let tmpl = document.createElement("template");
        tmpl.innerHTML = template;
        // 스타일 변경 1
        const styleSheet = new CSSStyleSheet();
        styleSheet.replaceSync(styleText);
        shadowRoot.adoptedStyleSheets= [styleSheet];
        // 스타일 변경 2
        shadowRoot.innerHTML = `
        <style>
            div > p {
                font-weight : bold;                
            }
        </style>`
        shadowRoot.appendChild(tmpl.content.cloneNode(true));
    }
}
customElements.define("my-custom-tag", CustomTag);

HTML로 Template 를 만들어서 사용하니 보기 한결 좋아졌습니다. 다른 방법으로는 html에 template태그로 template를 만들고 custom element가 생성될 때, template를 가져오는 방법도 있으나 이번 포스팅에선 제외하겠습니다.

Component 사용해보기
#

이제 만든 Custom HTMLElement를 사용해 봅시다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width" />
    <title>Custom Tag</title>
    <link rel="stylesheet" type="text/css" href="./index.css" />
    <script type="module" src="./custom-tag.js"></script>
</head>
<body>
    <div class="wrapper">
        <my-custom-tag>
            <p slot="card-title">카드 1</p>
        </my-custom-tag>
        <my-custom-tag>
            <p slot="card-title">카드 2</p>
            <img class="card-content" alt="stg" slot="card-content" src="./workflow.png"/>
        </my-custom-tag>
        <my-custom-tag>
            <p slot="card-title">카드 3</p>
            <img class="card-content" alt="stg" slot="card-content" src="./workflow.png"/>
        </my-custom-tag>
        <my-custom-tag>
            <p slot="card-title">카드 4</p>
            <img class="card-content" alt="stg" slot="card-content" src="./strategy.png"/>
        </my-custom-tag>
    </div>
</body>
</html>

재사용을 하기 위해 만들었기에 최대한 많이 사용해봤습니다.

CardExample

마치며..
#

여기까지 간단하게 Component를 만들어 봤습니다. 흥미가 생기셨다면 필요한 여러가지 이벤트를 등록하여 Component의 기능을 더욱 완벽하게 해 보시길 바랍니다. 저도 더 공부하여 유익할 정보를 공유하도록 노력하겠습니다.