(26)23.10.30 - [JS] target 만들기, html/css로 box 배치하기

DANA·2023년 10월 30일

KDT-구디아카데미

목록 보기
26/56

단축키
ctrl+shift+i: 개발자 도구
clg: vscode 콘솔출력

HTML

브라우저 구성요소
window + document(화면에 출력됨) + navigator(안 보임)

window = DOM(document) + BOM(navigator, location, fetch, storage) + Javascript(Array, Map, Date, ...)

c1.html

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  
  <!-- 모바일 화면크기 설정 -->
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  
  <title>실습 - 좌표</title>
  
  <!-- 외부 스타일 시트 'c1.css'를 불러옵니다. -->
  <link rel ="stylesheet" href="c1.css">
</head>
  
<body>
  <!-- 수평 라인을 나타내는 div 요소 -->
  <div class="line horizontal"></div>
  <!-- 수직 라인을 나타내는 div 요소 -->
  <div class="line vertical"></div>
  <!-- "target.png" 이미지 요소 -->
  <img class="target" src="target.png" alt="타겟 이미지">
  <!-- 좌표 텍스트를 나타내는 span 요소 -->
  <span class="label">(500,400)</span>
  
  <!-- 외부 JavaScript 파일 'c1.js'를 불러옵니다. -->
  <script src="c1.js"></script>
</body>
</html>

c1.css

/* 모든 요소에 대해 box-sizing을 변경하여
   패딩과 테두리를 포함한 요소 크기를 설정 */
*{
  box-sizing: border-box;
  left: 0;
  top: 0;
}

/* 전체 페이지의 배경색을 검정으로 설정 */
body {
  background-color: black;
}

/* '.line' 클래스 정의 */
.line { /* 선택자(.) */
  /* 부모 요소를 기준으로 절대 위치로 설정 */
  position: absolute; 
   /* 배경색을 흰색으로 설정 */
  background-color: white;
}

/* '.vertical' 클래스 정의 */
.vertical {
  /* 요소의 높이=화면의 높이(화면을 가득 채움) */
  height: 100%;
  /* 수직선 너비(두께) 1px */
  width: 1px;
  /* 가로 중앙에 요소 배치(x축) */
  left: 50%;
}

/* '.horizontal' 클래스 정의 */
.horizontal {
  /* 요소의 너비=화면의 너비 */
  width: 100%;
  /* 수평선 높이 1px */
  height: 1px;
  /* 세로 중앙에 요소 배치(y축) */
  top: 50%; 
}

/* '.label' 클래스 정의 */
.label {
  /* 텍스트 색상 */
  color: white;
  /* 부모 요소를 기준으로 절대 위치로 설정 */
  position: absolute;
  /* 세로 중앙에 요소 배치(y축). */
  top: 50%;
  /* 가로 중앙에 요소 배치(x축). */
  left: 50%;
  /* 요소를 중앙에서 오른쪽으로 20px, 아래로 20px 이동 */
  transform: translate(20px, 20px);
}

/* 'target' 요소 정의 */
.target {
  /* 부모 요소를 기준으로 절대 위치로 설정 */
  position: absolute;
  /* 세로 중앙에 요소 배치(y축). */
  top: 50%;
  /* 가로 중앙에 요소 배치(x축). */
  left: 50%;
  /* 요소를 왼쪽으로 50%, 위로 50% 이동시켜 중앙에 배치 */
  transform: translate(-50%, -50%);
}

c1.js

// 'target' 클래스를 가진 요소를 찾아 변수 'target'에 할당
const target = document.querySelector('.target');

// 'label' 클래스를 가진 요소를 찾아 변수 'label'에 할당
const label = document.querySelector('.label');

// 'load' 이벤트가 발생할 때 실행하는 함수를 등록
addEventListener('load',() => {
  // 페이지가 로드되면 'test'를 콘솔에 출력
  console.log('test');
  
  // 'target' 요소의 위치와 크기 정보를 가져와 변수 'domRect'에 할당
  const domRect = target.getBoundingClientRect();
  
  // 'domRect'에서 가로 너비를 가져와 'twidth' 변수에 할당
  const twidth = domRect.width;
  
  // 'domRect'에서 세로 높이를 가져와 'theight' 변수에 할당
  const theight = domRect.height;
  
  // 'twidth'와 'theight' 값을 콘솔에 출력
  console.log(`${twidth}, ${theight}`);
  
  // 마우스 이동 이벤트('mousemove')가 발생할 때 실행하는 함수를 등록
  document.addEventListener('mousemove',(event)=>{
    // 마우스 이벤트 객체에서 현재 마우스의 X 좌표를 가져와 'x' 변수에 할당
    const x = event.clientX;
    // 마우스 이벤트 객체에서 현재 마우스의 Y 좌표를 가져와 'y' 변수에 할당
    const y = event.clientY;
    
    // 'x'와 'y' 값을 콘솔에 출력
    console.log(`${event.clientX}, ${event.clientY}`);
  })
})

// const 상수선언시, let 변하는 값을 사용
// var - 호이스팅 이슈

동작 설명
1. 'load' 이벤트가 발생하면 페이지가 로드되고 'test'를 콘솔에 출력

2. 'target' 요소의 위치 및 크기 정보를 가져와 'twidth' 및 'theight' 변수에 저장하고 그 값을 콘솔에 출력

3. 'mousemove' 이벤트가 발생할 때마다 마우스의 X 및 Y 좌표를 가져와 'x' 및 'y' 변수에 저장하고 그 값을 콘솔에 출력(마우스의 위치를 추적하는 역할)

상속관계
window > document > c1.html
: document는 c1.html 전체를 받는 객체이다

d1.html

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  
  <!-- 뷰포트 설정을 지정(모바일 기기에서 웹 페이지가 화면 크기에 맞게 표시되도록) -->
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
  
<body>
  <!-- JavaScript 코드를 실행할 때 사용하는 요소 -->
  <script>
    // document.write 함수를 사용
    // wirte 함수는 browser에 쓴다 - h1 태그와 뉴스제목이라는 텍스트 노드를 쓴다고 볼 수 있다
    // h1태그는 안 보이는 대신 글자크기가 커짐 - 브라우저 인터프리터 역할을 해줌
    // 태그에는 인라인요소(크기가 없다: width=300px 반영 안됨)와 블록요소(자체크기가 있다)가 있다
    document.write("<h1>뉴스제목</h1>") // 아래 뉴스 내용은 줄바꿔 출력됨
    document.write("뉴스 내용") // 아래 내용은 한 줄에 모두 출력됨
    document.write("뉴스 내용 두 번째...")
  </script>
</body>
</html>

e1.html

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .rect {
      display: block;
      width: 150px;
      height: 150px;
      background-color: red;
      margin-bottom: 10px;
    }
  </style>
</head>
<body>
  <!-- span.rect*3 emmet키 -->
  <span class="rect">1</span>
  <span class="rect">2</span>
  <span class="rect">3</span>
</body>
</html>

인라인요소/블록요소

e2.html

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .rect {
      width: 150px;
      height: 150px;
      background-color: aqua;
      margin-bottom: 10px;
    }
  </style>
</head>
<body>
  <div class="rect">1</div>
  <div class="rect">2</div>
  <div class="rect">3</div>
</body>
</html>

브라우저 역할
1. DOM Tree 그린다
2. CSS가 존재하는 경우 1번에서 그려진 트리에 css 추가된 트리를 다시 그린다
3. CSS 적용된 화면이 출력 - Rendering

브라우저에 개발자 도구를 무조건 활용할 것
(디버깅, 예외처리 처럼)

  • 개발자 도구에서 element 확인 했었음 - 코드와 css를 직접 변경해서 결과 확인이 가능하다
  • network : 요청에 대한 서버 측의 응답 결과를 상수로 확인 가능함(200,304, 404, 405, 500(Exception-자바), 403)

c1.html

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>실습 - 좌표</title>
  <link rel ="stylesheet" href="c1.css">
  <!-- js가 외부 파일인 경우 다운로드에 시간이 발생될 수도 있다 -->
</head>
<body>
  <div class="line horizontal"></div>
  <div class="line vertical"></div>
  <img class="target" src="target.png" alt="타겟 이미지">
  <span class="label">(500,400)</span> 
  <script src="c1.js"></script>
  </div>
</body>
</html>

c1.js

  • JavaScript에서 변수 선언
    - const: 상수 / let: 변수
  • 호이스팅(hoisting): 자바스크립트에서 변수가 선언되기 전에 사용될 때 발생하는 현상
    (호이스팅은 JavaScript 엔진이 코드를 해석할 때 변수 선언을 끌어올리는 동작을 수행하기 때문에 발생)
  • var 변수는 선언이 호이스팅되어 변수가 선언되기 전에 접근 가능해지며, 이로 인해 예기치 않은 동작이 발생할 수 있음. 이러한 이슈로 인해 ES6(ES2015) 이후부터는 let과 const를 사용하여 블록 스코프를 가지는 변수를 더욱 안전하게 선언하는 것이 권장
const vertical = document.querySelector('.vertical');
const horizontal = document.querySelector('.horizontal');
const target = document.querySelector('.target');
const label = document.querySelector('.label');

addEventListener('load',() => {
  console.log('test');
  const domRect = target.getBoundingClientRect();
  const twidth = domRect.width;
  const theight = domRect.height;
  console.log(`${twidth}, ${theight}`);
  
  document.addEventListener('mousemove',(event)=>{
    const x = event.clientX;
    const y = event.clientY;
    console.log(`${event.clientX}, ${event.clientY}`);
  
    // 좌표값은 출력되지만, 가로와 세로 선이 그대로임
  	// 좌표에 따라 이동하려면?
  
  	// vertical 요소의 왼쪽 위치를 x 좌표로 설정하여 수직 라인을 이동
    vertical.style.left = `${x}px`;
  	// horizontal 요소의 상단 위치를 y 좌표로 설정하여 수평 라인을 이동
    horizontal.style.top = `${y}px`;
  	
  	// target 요소의 왼쪽 위치를 x 좌표로 설정하여 target 요소를 이동
    target.style.left = `${x}px`;
  
  	// target 요소의 왼쪽 위치를 y 좌표로 설정하여 target 요소를 이동
    target.style.top = `${y}px`;
  
  	// label 요소의 HTML 내용을 업데이트하여 현재 마우스 좌표를 표시
    label.innerHTML = `(${x}px,${y}px)`;
    // TextNode는 NodeName은 없는 NodeValue는 있다
    // label.innerHTML = `(100px,200px)`
  })
})

내용정리

c1.html과 c1.css 섞어쓰기
브라우저에는 DOM Tree만 그리는 엔진과 DOM Tree에 css가 가미된 Tree를 그리는 엔진이 따로 있다

실제 화면에 출력될 때는 태그에 css 속성이 반영된 태그 정보를 사용자 컴터가 다운로드 받는다
브라우저는 다운로드된 내용을 처리하는 것이다
즉, 서버와 동기화가 되어있지 못하다
이러한 동기화 처리는 JAVA와 섞어쓰기가 필요한 대목이겠다
html 태그는 순서대로 차례대로 읽혀지고 처리가 되는데 중간에 xxx.js를 만나면 다운로드를 다 받을 때까지 멈추게 된다. 따라서 지연이 발생하고 화면은 열리지 않게 된다.
그런데 이벤트 처리가 먼저인가 화면 처리가 먼저인가를 생각해보면 화면을 먼저
그리고 그 후속으로 이벤트 처리가 필요하다는 것을 알고 있다

그러면 defer옵션을 추가하여 그대로 아래로 진행 시킨다음 다운로드가 완료되었을 때
코드를 실행하게 되면 undefined 메세지를 피할 수 있을 것이다

어플리케이션 - navigator - (local,session)storage, cookie

console - 로그 출력 console.log(this), alert("숫자만 넣어주세요"), prompt(0~9사이의 숫자를 입력하세요)

배치

r1.html

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Position- Relative</title>
  <link rel="stylesheet" href="r1.css">
</head>
<body>
  <article class="container">
    <div></div>
    <div class="box">Box</div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
  </article>
</body>
</html>

r1.css

/* Universal Selector: 모든 요소에 빨간 실선 테두리를 추가 */ 
* {
  border: 1px solid red; /* 1 */
}
/* .container 클래스 배경 검정 */
.container {
  background-color: black; /* 2 */

}

div {
  width: 100px;
  height: 100px;
  background-color: skyblue;
  margin-bottom: 10px;
}

.box {
  background-color: orangered;
}

s1.html

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="s1.css">
</head>
<body>
    <div class="wrap">
      <div class="box1"></div>
      <div class="box2"></div>
    </div>
</body>
</html>
/*
    .wrap > .box1 + .box2
*/

s1.css

* {
    box-sizing: border-box;
    border: 1px solid red;
    left: 0;
    top: 0;
}

.wrap{
    width: 300px;
    height: 600px;
    border: 10px solid black;
    margin: 10px auto;
}

.wrap .box1 {
    width: 300px;
    height: 300px;
    background-color: skyblue;
}

.box2 {
    width: 300px;
    height: 300px;
    background-color: pink;
}

✏️ target은 하나의 이미지들을 모아 움직이는 것처럼 보이는 것

#구디아카데미 후기 #국비지원 IT개발자취업 #김승수 선생님

0개의 댓글