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

Javascript Custom HTMLElement 2

·3 초· 0 · 0 ·
yna
css html javascript

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의 기능을 더욱 완벽하게 해 보시길 바랍니다. 저도 더 공부하여 유익할 정보를 공유하도록 노력하겠습니다.