포포 일상 블로그

typescript 스터디 3. 사용해서 아코디언 메뉴 만들기 본문

dev/JS

typescript 스터디 3. 사용해서 아코디언 메뉴 만들기

dev포포 2021. 1. 8. 20:24

1. 구글에 아코디언 메뉴 만들기 예제를 검색한다.

2. 복 붙 한다. 는 장난이였고,

 

직접 만드는 것을 좋아해서 삽질을 차근차근해보도록 하겠습니다.

 

에디터는 자유지만 저는 vscode를 사용하였습니다.

 

우선 html 파일을 하나 만듭니다.

vscode를 사용하시면 emmet 기능을 사용하셔서! 누르시고 Ctrl + Space 바 누르시면 편하게 작성하실 수 있습니다.

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
</body>
</html>

 

혹시 안 쓰실 분들을 위해 코드입니다.

 

이후 라이브 서버를 켜시면 됩니다.

 

없으신 분들은 Ctrl + Shitft + X 누르시면 필요한 플러그인을 받으실 수 있는데 거기서 liveserver 검색하셔서 다운로드하시면 됩니다.

 

라이브 서버 켜는 방법은 Alt+ L + O 키를 누르시면 됩니다. (알트 + 라이브(L) + 오픈(O))의 첫 글자라고 생각하시면 됩니다.)

 

꺼는 방법은 반대로 Alt+ L + C 키입니다. (알트 + 라이브(L) + 캔슬(C))

 

서버를 켜신 후 스크립트 연결을 해줍시다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="app.js"></script>
</head>
<body>
    
</body>
</html>

app js로 스크립트를 넣은 이유는 실제 코드는 ts로 작성하고 컴파일된 js파일을 사용합니다.

 

app.ts 파일을 하나 만들고 vscode에서 Ctrl + ` 키를 동시에 눌러주면 쉘 창이 하나 뜹니다.

 

거기서 명령어로 tsc --watch./app.ts를 입력하여 코드가 수정됨과 동시에 컴파일이 될 수 있도록 만들어 줍니다.

 

타입 스크립트 설치가 아직이라면 참고해주세요.

 

push-pop.tistory.com/2

 

TypeScript 설치 및 설정.

www.typescriptlang.org/ Typed JavaScript at Any Scale. TypeScript extends JavaScript by adding types to the language. TypeScript speeds up your development experience by catching errors and providin..

push-pop.tistory.com

 

자 여기까지 잘 따라오셨으면 기본적인 세팅은 끝났습니다.

 

이제 내용을 작성하겠습니다.

 

<div class="container">
        <ul>
            <li>
                <h3>title 1</h3>
                <p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Laboriosam culpa ipsa necessitatibus eum,
                    nihil eos corrupti deserunt explicabo nisi reiciendis ratione dicta quis consequuntur, saepe id
                    pariatur hic amet minima?</p>
            </li>
            <li>
                <h3>title 2</h3>
                <p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Laboriosam culpa ipsa necessitatibus eum,
                    nihil eos corrupti deserunt explicabo nisi reiciendis ratione dicta quis consequuntur, saepe id
                    pariatur hic amet minima?</p>
            </li>
            <li>
                <h3>title 3</h3>
                <p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Laboriosam culpa ipsa necessitatibus eum,
                    nihil eos corrupti deserunt explicabo nisi reiciendis ratione dicta quis consequuntur, saepe id
                    pariatur hic amet minima?</p>
            </li>
        </ul>
    </div>

 

붙여오는 과정에서 살짝 밀렸는데 Ctrl + K + F 누르시면 줄 정렬이 됩니다 ~ 참고하세요 ~

Lorem 어쩌고 저쩌고 같은 경우에는 lorem 작성 후 Ctrl + Space바 누르시면 나오는 문자 클릭하시면 쭉 나옵니다!

 

대충 이런 형태면 완성입니다.

 

간단하게 스타일을 입혀볼까요?

 

<style>
     .container > ul {
         list-style: none;
     }
     .container > ul li {
         border: 1px solid #333;
     }

     h3 {
         margin: 0;
         background-color: aquamarine;
     }

     p {
         margin: 0;
         background-color: brown;
     }
</style>

 

이렇게 넣으시면

 

이러한 굉장한 모습을 보실 수 있습니다.

 

우선 아코디언 메뉴 자체의 기능에 좀 더 집중하기 위해 디자인은 잠시 이대로 두고 넘어가 보도록 하겠습니다.

 

우선 document 내부 element 들을 잡아야 합니다만 헤더에 script:src로 넣어놨기 때문에 콘텐츠가 다 로드된 후에 코드를 실행해야 합니다.

 

document.addEventListener('DOMContentLoaded', function () {
   
})

 

코드 입력 후에 li 태그들을 먼저 잡아주겠습니다.

const li = document.getElementsByTagName('li');

이런 식으로 잡으시면 도큐먼트 (최 상단 루트부터) 자식 중에 li 태그 전부 잡아옵니다.

근데 이렇게 잡았을 때 li 많으면 성능 조집니다. 그러니 조금 더 덜 쓰고 편리하게 타깃을 잡아주도록 하겠습니다.

 

const li = document.querySelectorAll('.container li');

위에 적었던 코드를 쿼리 실렉터로 바꿔줍시다.

제이쿼리 써보셨던 분들은 아마 좀 더 편하실 겁니다.

 

자. 이제 뭘 하냐 하면...

 

우선 css에서 lorem 친구들을 감싸고 있는 P태그에 display:none으로 숨겨보도록 하겠습니다.

 

이제 뭔가 접혀있는 느낌도 나고 슬슬 냄새가 납니다.

 

보통 제목을 클릭하면 접혔다가 펴졌다가 하는 효과기 때문에 저 타이틀에 클릭 이벤트를 먼저 주도록 하겠습니다.

 

const titles : NodeListOf<Element> = document.querySelectorAll('.container h3');

    for (let i = 0; titles.length > i; i++) {
        titles[i].addEventListener('click', function (this:any) {
            console.log(this)
        })
    }

 

클릭하면 자기 자신을 로그에 띄워주는 모습을 볼 수 있습니다.

 

일반적인 html에 타입 스크립트 처음 써봤는데 삽질 진짜 많이 했습니다. 

 

처음에 htmlCollection 잡아서 array.from(children).map으로 루프 돌리는데 lib 설정 등 다 해보고 foreach로 돌리면 되기는 하는데 foreach는 비동기라 잘 믿지 않아서 for of 돌리니 또 array만 포함이라서 다시 원점... 그래서 가장 베이스로 설정했습니다.. 나중에 다시 한번 관련된 삽질을 해봐야겠네요. 타입 스크립트 참 낯설다.. 하

 

잘 나오는 거 까지 확인했으니 이제 실질적인 기능을 만들도록 하겠습니다.

for (let i = 0; titles.length > i; i++) {
        titles[i].addEventListener('click', function (this:any) {
            const parent = this.parentNode;
            const lorem = parent.querySelector('p');

            lorem.style.display = (lorem.style.display === 'block') ? 'none' : 'block';
        });
    }

타이틀의 부모 요소를 잡고 그 하위에 있는 p태그를 잡아서 디스플레이 속성을 변경해주면 끝납니다.

 

이미지 출처 :

 namu.wiki/w/%EC%96%B4%EB%A8%B8!%20%EC%A0%80%EA%B1%B4!%20%EC%82%AC%EC%95%BC%ED%95%B4~?from=%EC%96%B4%EB%A8%B8%20%EC%A0%80%EA%B1%B4%20%EC%82%AC%EC%95%BC%ED%95%B4

 

근데 뭔가 어색한 건 기분 탓인가?

 

"어머! 애니메이션이 없잖아!"

 

transition 속성을 주려고 하는데 생각해보니 display에는 해당 속성이 먹지 않으니 높이값을 변경해서 스르륵 열리도록 바꿔보겠습니다.

 

대충 63 정도 처음에 나오네요.

 

        p {
            transition: all .3s ease-out;
            height: 0;
            margin: 0;
            overflow: hidden;
            background-color: brown;
        }

스타일을 이런 식으로 바꿔줍니다.

 

const parent = this.parentNode;
const lorem = parent.querySelector('p');

const height:string = (lorem.style.height === '63px') ? '0px' : '63px';
lorem.style.height = height;

eventListener 내부에 이런식으로 코드를 변경해줍시다.

 

그렇게 하면 

아주 잘 동작합니다.

 

최종 코드는 

 

html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .container > ul {
            list-style: none;
        }
        .container > ul li {
            border: 1px solid #333;
        }

        h3 {
            margin: 0;
            background-color: aquamarine;
        }

        p {
            transition: all .3s ease-out;
            height: 0;
            margin: 0;
            overflow: hidden;
            background-color: brown;
        }
    </style>
    <script src="app.js"></script>
</head>

<body>
    <div class="container">
        <ul>
            <li>
                <h3>title 1</h3>
                <p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Laboriosam culpa ipsa necessitatibus eum,
                    nihil eos corrupti deserunt explicabo nisi reiciendis ratione dicta quis consequuntur, saepe id
                    pariatur hic amet minima?</p>
            </li>
            <li>
                <h3>title 2</h3>
                <p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Laboriosam culpa ipsa necessitatibus eum,
                    nihil eos corrupti deserunt explicabo nisi reiciendis ratione dicta quis consequuntur, saepe id
                    pariatur hic amet minima?</p>
            </li>
            <li>
                <h3>title 3</h3>
                <p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Laboriosam culpa ipsa necessitatibus eum,
                    nihil eos corrupti deserunt explicabo nisi reiciendis ratione dicta quis consequuntur, saepe id
                    pariatur hic amet minima?</p>
            </li>
        </ul>
    </div>
</body>

</html>

 

typescript 

document.addEventListener('DOMContentLoaded', function () {
    const titles : NodeListOf<Element> = document.querySelectorAll('.container h3');

    for (let i = 0; titles.length > i; i++) {
        titles[i].addEventListener('click', function (this:any) {
            const parent = this.parentNode;
            const lorem = parent.querySelector('p');

            const height:string = (lorem.style.height === '63px') ? '0px' : '63px';
            lorem.style.height = height;
        });
    }
})

 

입니다.

 

타입 스크립트로 아코디언 메뉴 만들기 봐주셔서 감사합니다.

 

결론.

 1. 타입 스크립트를 뭔가 자바스크립트로 너무 생각했나;

 2. 역시 아코디언 메뉴는 ☆★ 부트스트랩 ☆★

 3. 코드 블록 예쁜거 쓰는 법 아는 분 공유좀요 ㅠ

 4. 그래도 재밌었다~~~~~~

 

'dev > JS' 카테고리의 다른 글

javascript + canvas 우주 만들기.  (0) 2021.01.11
javascript 로 캘린더 + 투두리스트 만들기  (2) 2021.01.10
typescript 스터디 2.  (0) 2021.01.07
typescript 스터디 1.  (0) 2021.01.07
typescript 스터디 시작.  (0) 2021.01.07