프론트엔드/Javascript 연습과제 해답

요소의 좌표 계산하기 연습과제 해답

syleemomo 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