ABOUT ME

웹개발과 일상에 대해 포스팅하는 블로그입니다.

Today
Yesterday
Total
  • 요소의 좌표 계산하기 연습과제 해답
    프론트엔드/Javascript 연습과제 해답 2024. 2. 28. 07:39
    728x90

    연습과제 1

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
      <link rel="stylesheet" href="style.css">
    </head>
    <body>
      <header>
        <a href="#">logo</a>
        <nav>
          <ul>
            <li>
              <a href="#" class="menu">home</a>
              
            </li>
            <li>
              <a href="#" class="menu">about</a>
              
            </li>
            <li>
              <a href="#" class="menu">contact</a>
              
            </li>
          </ul>
        </nav>
      </header>
      <script src="app.js"></script>
    </body>
    </html>
    :root{
      --primary-color: yellowgreen;
      --header-height: 70px;
    }
    *{
      box-sizing: border-box;
    }
    body{
      margin: 0; padding: 0;
    }
    a{
      text-decoration: none;
      color: var(--primary-color);
    }
    a:hover{
      color: yellow;
    }
    ul{
      list-style: none;
      margin: 0; padding: 0;
    }
    header{
      /* border: 1px solid red; */
      display: flex;
      justify-content: space-between;
      align-items: center;
      position: fixed;
      left: 0; right: 0; top: 0;
      z-index: 1;
      background-color: #fff;
      box-shadow: 0 .3rem .3rem rgba(0, 0, 0, .1);
      height: var(--header-height);
    }
    header > nav > ul{
      display: flex;
      gap: 5rem;
      margin-right: 5rem;
    }
    header > nav .menu{
      position: relative;
      /* border: 1px solid red; */
    }
    header > nav .sub-menu{
      position: absolute;
      top: calc(var(--header-height) + 10px);
      border: 2px solid greenyellow;
      padding: .5rem 1rem;
      opacity: 1; 
      transition: .5s ease-in-out;
    }
    const navigation = document.querySelector('header > nav')
    const homeMenus = ["home-sub-1", "home-sub-2", "home-sub-3"]
    const aboutMenus = ["about-sub-1", "about-sub-2", "about-sub-3"]
    const contactMenus = ["contact-sub-1", "contact-sub-2", "contact-sub-3"]
    const menuMap = {
      home: homeMenus,
      about: aboutMenus,
      contact: contactMenus
    }
    let submenu 
    
    function createDropdown(menus){
      const ul = document.createElement('ul')
      ul.className = "sub-menu"
      for(let menu of menus){
        ul.innerHTML += `<li><a href="#">${menu}</a></li>`
      }
      return ul 
    }
    function getLeftPositionOfElement(elem){
      return elem.getBoundingClientRect().left
    }
    
    function showSubmenu(e){
      console.log(e.target, e.target.innerText)
    
      if(e.target.className === 'menu'){
        const currentSubmenu = e.target.parentElement.querySelector('.sub-menu') // 현재 클릭한 메뉴와 기존에 클릭한 메뉴가 동일한 경우 서브메뉴를 지우기 전에 검색해야 검색이 됨
        if(submenu) submenu.remove()
    
        if(currentSubmenu !== submenu){ // 현재 클릭한 메뉴의 서브메뉴와 기존에 열려있는 서브메뉴가 다른 경우 현재 클릭한 메뉴에 서브메뉴 추가
          const left = getLeftPositionOfElement(e.target)
          submenu = createDropdown(menuMap[e.target.innerText])
          submenu.style.left = left + 'px'
          e.target.parentElement.appendChild(submenu)
        }
      }
    }
    
    navigation.addEventListener('click', showSubmenu)

     

    연습과제 2

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
      <link rel="stylesheet" href="style.css">
    </head>
    <body>
      <div class="bg">
      </div>
      <script src="app.js"></script>
    </body>
    </html>
    body{
      margin: 0; padding: 0;
      height: 300vh;
      
      display: flex;
      justify-content: center;
      align-items: center;
    }
    .bg{
      width: 50vw; height: 30vw;
      background: url(https://image-cdn.hypb.st/https%3A%2F%2Fkr.hypebeast.com%2Ffiles%2F2023%2F09%2Fstudio-ghibli-to-be-acquired-by-nippon-television-holdings-details-info-01.jpg?cbr=1&q=90) no-repeat center;
      background-size: cover;
      transition: 1s ease-in-out;
    }
    .fix{
      position: fixed;
      bottom: 0; 
      width: 100%; height: 100vh;
    }
    const bg = document.querySelector('.bg')
    const documentHeight = document.documentElement.clientHeight
    
    window.addEventListener('scroll', function(){
      if(bg.getBoundingClientRect().top < documentHeight/2){
        bg.classList.add('fix')
      }
    })

     

    연습과제 3

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
      <link rel="stylesheet" href="style.css">
    </head>
    <body>
      <script src="app.js"></script>
    </body>
    </html>
    body{
      margin: 0; padding: 0;
    }
    .circle{
      border-radius: 50%;
      position: absolute;
      transform: translate(-50%, -50%);
      width: 0; height: 0; opacity: 0;
      transition: 1s ease-in-out;
    }
    const maxRadius = 100
    const documentHeigth = document.documentElement.clientHeight
    const documentWidth = document.documentElement.clientWidth
    
    function pickRandomNum(n){
      return Math.floor(Math.random()*n)
    }
    function createCircle(x, y, r){
      const circle = document.createElement('span')
      circle.className = 'circle'
      circle.style.left = x + 'px'
      circle.style.top = y + 'px'
      circle.style.backgroundColor = `rgb(${pickRandomNum(255)}, ${pickRandomNum(255)}, ${pickRandomNum(255)}, ${Math.random()})`
      setTimeout(() => {
        circle.style.width = 2*r + 'px'
        circle.style.height = 2*r + 'px'
        circle.style.opacity = '1'
      }, 1000);
      return circle
    }
    
    
    function addCircle(){
      let x, y, r
      do{
        x = pickRandomNum(documentWidth)
        y = pickRandomNum(documentHeigth)
        r = pickRandomNum(maxRadius)
      }while(x-r < 0 || x+r > documentWidth || y-r < 0 || y+r > documentHeigth || r === 0)
    
      const circle = createCircle(x, y, r)
      document.body.appendChild(circle)
    }
    setInterval(addCircle, 1000)

     

    연습과제 4

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
      <link rel="stylesheet" href="style.css">
    </head>
    <body>
      <script src="app.js"></script>
    </body>
    </html>
    body{
      margin: 0; padding: 0;
    }
    .text{
      position: absolute;
      width: 0; height: 0; opacity: 0; font-size: 0;
      transition: 1s ease-in-out;
    }
    const maxSize = 200, maxFontSize = 50, text = 'hello world!'
    const documentHeigth = document.documentElement.clientHeight
    const documentWidth = document.documentElement.clientWidth
    
    function pickRandomNum(n){
      return Math.floor(Math.random()*n)
    }
    function createMsg(x, y, w, h, t, fs){
      const msg = document.createElement('span')
      msg.className = 'text'
      msg.innerText = t
      msg.style.left = x + 'px'
      msg.style.top = y + 'px'
      msg.style.color = `rgb(${pickRandomNum(255)}, ${pickRandomNum(255)}, ${pickRandomNum(255)}, ${Math.random()})`
      setTimeout(() => {
        msg.style.width = w + 'px'
        msg.style.height = h + 'px'
        msg.style.opacity = '1'
        msg.style.fontSize = fs + 'px'
      }, 1000);
      return msg
    }
    
    
    function addCircle(){
      let x, y, w, h, fs
      do{
        x = pickRandomNum(documentWidth)
        y = pickRandomNum(documentHeigth)
        w = pickRandomNum(maxSize)
        h = pickRandomNum(maxSize)
        fs = pickRandomNum(maxFontSize)
      }while(x < 0 || x+w > documentWidth || y < 0 || y+h > documentHeigth || w === 0 || h === 0)
    
      const msg = createMsg(x, y, w, h, text, fs)
      document.body.appendChild(msg)
    }
    setInterval(addCircle, 1000)
    728x90
Designed by Tistory.