디자인 자격증/웹디자인기능사

D-1: 웹디자인기능사 실기시험 공개문제 풀이(자바스크립트)

saejun 2023. 11. 21. 00:00
반응형

D-1 조이컨트리클럽 와이어프레임 살펴보기

기존 A, B, C 유형과는 다르게 D유형은 반응형으로 제작해야 한다.

 

영역별로 구현해야 되는 애니메이션:

  • 서브메뉴 - 세로형태 슬라이드 애니메이션
  • 슬라이드 - 페이드 인&아웃 형태의 애니메이션
  • 탭메뉴
  • 레이어팝업

D-1: 조이컨트리클럽 와이어프레임 구성하기

Visual Studio Code를 실행하고, 아래와 같은 구조로 파일을 생성한다:

 

 

HTML을 사용해서 와이어프레임의 기본 구조를 만든다. 먼저 3개의 영역(Aside, Main, Footer)을 만든다:

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>조이컨트리클럽</title>
    
     <!-- css -->
    <link rel="stylesheet" href="css/style.css">

    <!-- script -->
    <script src="script/script.js"></script>
</head>
<body>
    <div id="wrap">
        <aside id="aside">

        </aside>
        <!-- //aside -->

        <main id="main">

        </main>
        <!-- //main -->

        <footer id="footer">

        </footer>
        <!-- //footer -->
    </div>
</body>
</html>

 

CSS

최상단에 reset을 적용시키고 영역별로 정의해 준다. 고정형이 아닌 반응형이기 때문에 cal()를 사용한다:

@charset "UTF-8";

/* reset */
* {
    margin: 0;
    padding: 0;
    color: #333;
}

a {
    text-decoration: none;
    color: #333;
}

li {
    list-style: none;
}

img {
    vertical-align: top;
    width: 100%;
}

#wrap {
    width: 100%;
    display: flex;
    flex-wrap: wrap;
}
#aside {
    width: 200px;
    height: 850px;
    background-color: #b8b8b8;
}
#main {
    width: calc(100% - 200px);
    height: 850px;
    background-color: #d2d2d2;
}
#footer {
    width: 100%;
    height: 100px;
    background-color: #dadada;
}

 

브라우저

 

이이서 각각의 구역을 세분화한다:

 

HTML

<body>
    <div id="wrap">
        <aside id="aside">
            <h1 class="logo"></h1>
            <nav class="nav"></nav>
        </aside>
        <!-- //aside -->

        <main id="main">
            <div class="slider"></div>
            <div class="banner"></div>
            <div class="info"></div>
        </main>
        <!-- //main -->

        <footer id="footer">
            <div class="footer1"></div>
            <div class="footer2"></div>
            <div class="footer3"></div>
        </footer>
        <!-- //footer -->
    </div>
</body>
</html>

 

CSS

/* wrap */
#wrap {
    width: 100%;
    display: flex;
    flex-wrap: wrap;
}

/* aside */
#aside {
    width: 200px;
    height: 850px;
}
#aside .logo {
    width: 100%;
    height: 100px;
    background-color: #b8b8b8;
}
#aside .nav {
    width: 100%;
    height: 750px;
    background-color: #f9f9f9;
}

/* main */
#main {
    width: calc(100% - 200px);
    height: 850px;
}
#main .slider {
    width: 100%;
    height: 400px;
    background-color: #6c6c6c;
}
#main .banner {
    width: 100%;
    height: 200px;
    background-color: #858585;
}
#main .info {
    width: 100%;
    height: 250px;
    background-color: #3f3f3f;
}

/* footer */
#footer {
    width: 100%;
    display: flex;
}
#footer .footer1 {
    width: 200px;
    height: 100px;
    background-color: #dadada;
}
#footer .footer2 {
    width: calc(100% - 500px);
    height: 100px;
    background-color: #6f6f6f;
}
#footer .footer3 {
    width: 300px;
    height: 100px;
    background-color: #999999;
}

 

브라우저


A영역(Aside) 로고 코딩하기

먼저 최상단에 위치한 로고 영역을 코딩한다. 포토샵을 사용해 헤더와 푸터용 워드타입 로고를 제작한다:

사이즈: 200PX & 40PX, PNG 포맷

 

HTML

 <div id="wrap">
        <aside id="aside">
            <h1 class="logo">
                <a href="#"><img src="images/logo.png" alt="조이컨트리클럽 로고"></a>
            </h1>
            <nav class="nav"></nav>
        </aside>
        <!-- //aside -->

 

CSS

#aside .logo {
    width: 100%;
    height: 100px;
    display: flex;
    align-items: center;
    justify-content: center;
}

 

브라우저

 


A영역(Aside) 메뉴 코딩하기

시험지에 출제된 사이트맵을 참고하여 메뉴구조를 짠다:

 

HTML

 <div id="wrap">
        <aside id="aside">
            <h1 class="logo">
                <a href="#"><img src="images/logo.png" alt="조이컨트리클럽 로고"></a>
            </h1>
            <nav class="nav">
                <ul>
                    <li><a href="#">CLUB</a>
                        <ul class="submenu">
                            <li><a href="#">클럽소개</a></li>
                            <li><a href="#">시설안내</a></li>
                        </ul>
                    </li>
                    <li><a href="#">BOOKING</a>
                        <ul class="submenu">
                            <li><a href="#">요금안내</a></li>
                            <li><a href="#">예약안내</a></li>
                            <li><a href="#">위약안내</a></li>
                        </ul>
                    </li>
                    <li><a href="#">INFORMATION</a>
                        <ul class="submenu">
                            <li><a href="#">명예의 전당</a></li>
                            <li><a href="#">이벤트</a></li>
                            <li><a href="#">자료실</a></li>
                            <li><a href="#">포토갤러리</a></li>
                        </ul>
                    </li>
                    <li><a href="#">COMMUNITY</a>
                        <ul class="submenu">
                            <li><a href="#">공지사항</a></li>
                            <li><a href="#">Q&A</a></li>
                        </ul>
                    </li>
                </ul>
                <p class="spot">
                    <a href="#">로그인</a>
                    <a href="#">회원가입</a>
                </p>    
            </nav>
        </aside>
        <!-- //aside -->

 

CSS

먼저 메인메뉴를 정의한다:

/* aside */
#aside {
    width: 200px;
    height: 850px;
   
}
#aside .logo {
    width: 100%;
    height: 100px;
    display: flex;
    align-items: center;
    justify-content: center;
}
#aside .nav {
    width: 100%;
    height: 750px;
}
#aside .nav > ul {
    margin: 10px;
}
#aside .nav > ul > li > a {
    display: block;
    padding: 10px 40px;
    font-size: 20px;
    text-align: center;
    background-color: #d3d3d3;
}
#aside .nav > ul > li > a:hover {
    background-color: #aeaeae;
}
#aside .nav > ul > li > ul {
    display: none;
}

 

브라우저

 

이어서 세부메뉴를 정의한다:

 

CSS

/* aside */
#aside {
    width: 200px;
    height: 850px;
   
}
#aside .logo {
    width: 100%;
    height: 100px;
    display: flex;
    align-items: center;
    justify-content: center;
}
#aside .nav {
    width: 100%;
    height: 750px;
}
#aside .nav > ul {
    margin: 10px;
}
#aside .nav > ul > li > a {
    display: block;
    padding: 10px 40px;
    font-size: 20px;
    text-align: center;
    background-color: #d3d3d3;
}
#aside .nav > ul > li > a:hover {
    background-color: #aeaeae;
}
#aside .nav > ul > li > ul {
    /* display: none; */
}
#aside .nav > ul > li > ul > li > a {
    display: block;
    padding: 10px 40px;
    text-align: center;
    background-color: #eeeeee;
}
#aside .nav > ul > li > ul > li > a:hover {
    background-color: #6e6e6e;
}

 

브라우저

 

마지막으로 하단의 로그인 | 회원가입 영역을 정의한다:

#aside .nav > p {
    text-align: center;
    margin-top: 20px;
}
#aside .nav > p a::after {
    content: '|';
    margin-left: 10px;
}
#aside .nav > p a:last-child::after {
    content: '';
    margin-left: 0;
}
#aside .nav > p a:hover {
    text-decoration: underline;
}

 

브라우저


B영역(메인) 슬라이드 코딩하기

3개의 이미지를 사용해 슬라이드를 구조를 잡는다. 반응형 슬라이더는 기존의 고정형(A, B, C 유형)과는 다르게 HTML이 아닌 CSS에서 이미지를 백그라운드 형태로 삽입해야 한다:

 

HTML

   <main id="main">
            <div class="slider">
                <div class="sliderWrap">
                    <div class="slider s1">
                        <div class="text">
                            <h2>조이컨트리클럽 1</h2>
                        </div>
                    </div>
                    <div class="slider s2">
                        <div class="text">
                            <h2>조이컨트리클럽 2</h2>
                        </div>
                    </div>
                    <div class="slider s3">
                        <div class="text">
                            <h2>조이컨트리클럽 3</h2>
                        </div>
                    </div>
                </div>
            </div>
            <!-- //slider -->

 

CSS

먼저 이미지와 텍스트 위치를 잡아준다:

/* slider */
#main .slider {
    width: 100%;
    height: 400px;
}
#main .slider .sliderWrap .slider {
    position: relative;
    background-size: cover;
    background-position: center;
}
#main .slider .sliderWrap .slider.s1 {
    background-image: url(../images/slider01.png);
}
#main .slider .sliderWrap .slider.s2 {
    background-image: url(../images/slider02.png);
}
#main .slider .sliderWrap .slider.s3 {
    background-image: url(../images/slider03.png);
}
#main .slider .sliderWrap .slider .text {
    background-color: rgba(0, 0, 0, 0.4);
    padding: 10px 20px;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
}
#main .slider .sliderWrap .slider .text h2 {
    font-size: 30px;
    color: #fff;
}

 

브라우저

 

추후 페이드 인&아웃 형태의 슬라이드 애니메이션을 구현해야 하기 때문에 아래처럼 CSS 코드를 수정한다(슬라이드 이미지를 모두 한 곳으로 모은다):

 

CSS

#main .slider .sliderWrap {
    position: relative;
}
#main .slider .sliderWrap .slider {
    position: absolute;
    background-size: cover;
    background-position: center;
}

 

브라우저 화면


C영역(메인) 배너 코딩하기

이미지와 화살표 이미지를 활용해 중앙 부분에 배너를 만든다:

 

HTML

<div class="banner">
                <a href="#">
                    <div class="photo"><img src="images/banner.jpg" alt="연단체 추가 모집 안내">
                    </div>
                    <div class="text">
                        <h3>소소한 멤버들과 함께 2023년 연단체 추가 모집 안내!</h3>
                        <ul>
                            <li>모집기간: 2023년 2월 23일(목)부터 마감 시까지</li>
                            <li>운영시간: 주중(월~금요일) 1부(7~8시) / 2부(12시) </li>
                        </ul>
                    </div>
                    <div class="arrow">
                        <img src="images/arrow.png" alt="바로가기">
                    </div>
                </a>
            </div>
            <!-- //banner -->

 

CSS

/* banner */
#main .banner {
    width: 100%;
    height: 200px;
    background-color: #858585;
}
#main .banner a {
    display: block;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
}
#main .banner .photo {
    width: 250px;
    height: 150px;
    overflow: hidden;
    margin-right: 120px;
}
#main .banner .text {
    margin-right: 120px;
}
#main .banner .text h3 {
    font-size: 30px;
}
#main .banner .text ul {
    margin-top: 20px;
}
#main .banner .text ul li {
    margin-top: 5px;
    font-size: 18px;
}
#main .banner .arrow {
    width: 80px;
}

 

브라우저


C영역(메인) 탭메뉴 코딩하기

HTML

<div class="info">
                <div class="info-menu">
                    <a href="#" class="active">공지사항</a>
                    <a href="#">갤러리</a>
                </div>
                <div class="info-cont">
                    <div class="notice">
                        <ul>
                            <li><a href="#">공지사항 1</a><span>2023.11.20</span></li>
                            <li><a href="#">공지사항 2</a><span>2023.11.20</span></li>
                            <li><a href="#">공지사항 3</a><span>2023.11.20</span></li>
                            <li><a href="#">공지사항 4</a><span>2023.11.20</span></li>
                        </ul>
                    </div>
                    <div class="gallery">
                        <ul>
                            <li><a href="#"><img src="images/gallery01.png" alt="갤러리1"></a></li>
                            <li><a href="#"><img src="images/gallery02.png" alt="갤러리2"></a></li>
                            <li><a href="#"><img src="images/gallery03.png" alt="갤러리3"></a></li>
                        </ul>
                    </div>
                </div>
            </div>
        </main>
        <!-- //main -->

 

CSS

#main .info {
    width: 100%;
    height: 250px;
    padding: 20px;
    box-sizing: border-box;
    background-color: #fff;
}
#main .info .infoWrap {
    background-color: #000;
}
#main .info .info-menu {
    display: flex;
}
#main .info .info-menu a {
    font-size: 24px;
    background-color: #82c788;
    padding: 10px 40px;
    height: 100%;
}
#main .info .info-menu a.active {
    background-color: #2aae35;
}
#main .info .info-cont .notice {
    background-color: #2aae35;
    padding: 14px 50px;
    box-sizing: border-box;
    display: none;
}
#main .info .info-cont .notice li {
    display: flex;
}
#main .info .info-cont .notice li a {
    width: 70%;
    line-height: 1.8;
    font-size: 18px;
    border-bottom: 2px solid #333;
}
#main .info .info-cont .notice li a:hover {
    text-decoration: underline;
}
#main .info .info-cont .notice li span {
    width: 30%;
    line-height: 1.8;
    font-size: 18px;
    border-bottom: 2px solid #333;
    text-align: right;
}
#main .info .info-cont .gallery {
    display: none;
    padding: 24px;
    background-color: #2aae35;
}
#main .info .info-cont .gallery ul {
    display: flex;
}
#main .info .info-cont .gallery ul li {
    width: 120px;
    padding: 0 30px;
}
#main .info .info-cont .gallery ul li a {
    border: 4px solid transparent;
    display: block;
}
#main .info .info-cont .gallery ul li a:hover {
    background-color: #0a5b10;
}

 

브라우저 화면


D영역(푸터) 코딩하기

<footer id="footer">
            <div class="footer1">
                <div class="logo">
                    <a href="#"><img src="images/logo_f.png" alt=""></a>
                </div>
            </div>
            <div class="footer2">
                COPYRIGHTⓒ by WEBDESIGN. ALL RIGHTS RESERVED
            </div>
            <div class="footer3">
                <div class="sns">
                    <ul>
                        <li><a href="#"><img src="images/sns1.png" alt="페이스북"></a></li>
                        <li><a href="#"><img src="images/sns2.png" alt="인스타그램"></a></li>
                        <li><a href="#"><img src="images/sns3.png" alt="유튜브"></a></li>
                    </ul>
                </div>
            </div>
        </footer>
        <!-- //footer -->

 

CSS

/* footer */
#footer {
    width: 100%;
    display: flex;
    background-color: #dadada;
}
#footer .footer1 {
    width: 200px;
    height: 100px;
    display: flex;
    align-items: center;
    justify-content: center;
}
#footer .footer2 {
    width: calc(100% - 500px);
    height: 100px;
    display: flex;
    align-items: center;
    justify-content: center;
}
#footer .footer3 {
    width: 300px;
    height: 100px;
}
#footer .footer3 .sns {
    padding: 20px;
    box-sizing: border-box;
}
#footer .footer3 .sns ul {
    display: flex;
    justify-content: center;
    align-items: center;
}
#footer .footer3 .sns li {
    padding: 10px;
    box-sizing: border-box;
}

 

브라우저 화면


코딩을 여기까지 완료하면 컬러 테마를 적용한다:


[추가] 이미지 슬라이더 우측 상단 바로가기 아이콘 코딩

슬라이더 우측 상단의 바로가기 아이콘 영역을 코딩한다:

 

HTML

<div class="shortcut">
                <ul>
                    <li><a href="#">
                        <img src="images/icon01.png" alt="갤러리">
                        <span>갤러리</span>
                    </a>
                    </li>
                    <li><a href="#">
                        <img src="images/icon02.png" alt="자료실">
                        <span>자료실</span>
                    </a>
                    </li>
                    <li><a href="#">
                        <img src="images/icon03.png" alt="전화문의">
                        <span>전화문의</span>
                    </a>
                    </li>
                </ul>
            </div>
            <!-- //shortcut -->

 

CSS

/* shortcut */
#main .shortcut {
    position: absolute;
    right: 30px;
    top: 30px;
}
#main .shortcut ul {
    background-color: #fff;
    padding: 10px 20px;
    box-sizing: border-box;
}
#main .shortcut ul li {
    width: 50px;
    text-align: center;
    margin-bottom: 10px;
    border-bottom: 3px solid #0a5b10;
    padding-bottom: 10px;
}
#main .shortcut ul li a img {
    margin-bottom: 5px;
}
#main .shortcut ul li a span {
    font-size: 14px;
}
#main .shortcut ul li a span:hover {
    color: #0f9c1b;
}

 

HTML


레이어 팝업 코딩

마지막으로 레이어 팝업을 코딩한다:

 

HTML

<div class="popup-view">
            <h2>조이컨트리클럽 이벤트대회 개최 안내</h2>
            <p>
                조이컨트리클럽에서 이벤트대회를 개최합니다. 더 많은 정보는 홈페이지에서 확인 부탁드립니다. 감사합니다.
            </p>
            <a href="#" class="popup-close">닫기</a>
        </div>
        <!-- //popup -->

 

CSS

/* popup */
.popup-view {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%,-50%);
    width: 400px;
    height: 400px;
    background-color: #63b86a;
    padding: 20px;
    box-sizing: border-box;
    border: 4px solid #0a5b10;
}
.popup-view h2 {
    border-bottom: 4px solid #0a5b10;
    padding-bottom: 5px;
}
.popup-view p {
    margin-top: 20px;
    font-size: 16px;
}
.popup-close {
    position: absolute;
    padding: 10px 40px;
    background-color: #0f9c1b;
    color: #fff;
    bottom: 30px;
    left: 50%;
    transform: translateX(-50%);
}

 

브라우저

 

여기까지 진행했다면 W3C 유효성 검사를 진행해서 HTML과 CSS에 이상이 있는지 확인한다. 이상이 없다면 자바스크립트로 넘어간다.


자바스크립트

메뉴 Javascript

window.onload = function(){
    //메뉴
    let navList = document.querySelectorAll(".nav > ul > li");

    //자바스크립트 CSS
    let submenus = document.querySelectorAll(".nav > ul > li > ul");

    submenus.forEach(function (submenu){
        submenu.style.display = "block";
        submenu.style.height = "0";
        submenu.style.overflow = "hidden";
        submenu.style.transition = "all 600ms";
    });

    navList.forEach(navItem => {
        navItem.addEventListener("mouseover", function(){
            let subMenu = this.querySelector(".submenu");
            subMenu.style.height = subMenu.scrollHeight + "px";
        });
    });
    navList.forEach(navItem => {
        navItem.addEventListener("mouseout", function(){
            this.querySelector(".submenu").style.height = "0px";
        });
    });
  }

슬라이드 Javascript

페이드 인&아웃 형태로 구현한다:

  //슬라이드
    let currentIndex = 0;
    const slider = document.querySelectorAll(".sliderWrap .slider");
    slider.forEach(img => img.style.opacity = "0");
    slider[0].style.opacity = "1";

    setInterval(() => {
        let nextIndex = (currentIndex +1) % slider.length;

        slider[currentIndex].style.opacity = "0";
        slider[nextIndex].style.opacity = "1";
        slider.forEach(img => img.style.transition = "all 1s");

        currentIndex = nextIndex;
        
    }, 3000);

탭메뉴 Javascript

//탭메뉴
    const tabBtn = document.querySelectorAll(".info-menu > a");
    const tabCont = document.querySelectorAll(".info-cont > div");

    tabCont.forEach(el => el.style.display = "none");
    tabCont[0].style.display = "block";

    tabBtn.forEach((tab, index)=> {
        tab.addEventListener("click", ()=> {
            tabBtn.forEach(tab => tab.classList.remove("active"));
            tab.classList.add("active");

            tabCont.forEach(cont => cont.style.display = "none");
            tabCont[index].style.display = "block";
        });
    });

레이어팝업 Javascript

자바스크립트 작성하기 전에 HTML로 이동해서 공지사항 첫 번째 콘텐츠에 Class를 추가한다:

<div class="info-cont">
                    <div class="notice">
                        <ul>
                            <li class="popup-btn"><a href="#">공지사항 1</a><span>2023.11.20</span></li>
                            <li><a href="#">공지사항 2</a><span>2023.11.20</span></li>
                            <li><a href="#">공지사항 3</a><span>2023.11.20</span></li>
                            <li><a href="#">공지사항 4</a><span>2023.11.20</span></li>
                        </ul>
                    </div>

 

이후 아래 자바스크립트를 작성한다:

//레이어 팝업
    document.querySelector(".popup-btn").addEventListener("click",function(){
        document.querySelector(".popup-view").style.display = "block"
    });
    document.querySelector(".popup-close").addEventListener("click",function(){
        document.querySelector(".popup-view").style.display = "none"
    });

최종완성 코드 & 화면

최종코드

https://github.com/saejunahn/Craftsman-Web-Design/tree/main/D1

 

최종화면

https://saejunahn.github.io/Craftsman-Web-Design/D1/

반응형