25.03.31 (월) 35일차 JS

허배령·2025년 3월 31일

괴발개발 TIL

목록 보기
45/54

배열

  • 변수를 묶음으로 다루는 것 (자료구조의 기초)
    (JS 변수의 특징 : 대입되는 값에 따라서 자료형이 변함)
    -> JS 배열 : 자료형 상관 없이 여러 값을 한 번에 다룸
  • JS 배열의 특징
  1. 자료형 제한 X (하지만 보통은 한 가지 자료형만 저장한다)
  2. 길이 제한 X (자동으로 배열 길이가 늘었다, 줄었다 한다)

[JS 배열 선언 방법]

1. const arr = new Array();	// 0칸짜리 배열(비어있는 배열) 생성

2. const arr = new Array(3); // 3칸짜리 배열 생성
							// 단, 각 칸의 값은 비어있음

3. const arr = [];	// 0칸짜리 배열 생성
					// [] : 배열 기호

4. const arr [1,2,3];	// 3칸짜리 배열 생성
							  // 각 칸이 값으로 채워져 있음
# JS

  // 배열 선언 및 기초 사용법
  function check1() {

  // 배열 선언 방법 확인
  const arr1 = new Array();
  const arr2 = new Array(3);
  const arr3 = [];
  const arr4 = ["사과", "바나나", "딸기"];

  console.log(arr1);
  console.log(arr2);
  console.log(arr3);
  console.log(arr4);



  // 배열명.length : 배열의 길이
  // (배열에 있는 칸 수 또는 저장된 데이터 수)
  console.log(arr1.length);
  console.log(arr2.length);
  console.log(arr3.length);
  console.log(arr4.length);

  // 배열의 index
  // 배열명[index]
  // -> 배열의 해당 인덱스에 존재하는 데이터를 반환
  console.log('arr4[0] : ', arr4[0]);
  console.log('arr4[1] : ', arr4[1]);
  console.log('arr4[2] : ', arr4[2]);


 // 배열명[index] = 값;
  // -> 해당 인덱스에 지정된 값 대입

  arr2[0] = 100;  // number
  arr2[1] = "점심 안 싸옴 ㅠ" // String
  arr2[2] = true; // boolean

  console.log("arr2 : ", arr2);
  // JS 배열의 특징 : 인덱스별로 자료형을 다르게 지저할 수 있다!


  // 길이 제한이 없다 -> 값을 배열에 원하는 만큼 추가 가능
  arr1[0] = "가";
  arr1[1] = "나";
  arr1[2] = "다";

  console.log("arr1 :" , arr1);

  arr1[4] = "마";
  console.log("arr1 :" , arr1);
  // 원하는 index에 값을 마음대로 추가할 수 있다.
  // -> 중간에 건너뛴 index는 빈칸으로 채워짐.


// 배열과 for문
  // for문을 이용해서 배열 요소 초기화 하기

  const arr = [];

  for(let i = 0; i <= 3; i++) {
    arr[i] = i * 10;
  }

  console.log("arr: ", arr);


    <button onclick="check3()">점심 메뉴 뽑기</button>
    <h4>오늘의 점심 : <span id="menuResult"></span></h4>
// 점심메뉴 뽑기
    // 결과 출력 span
    const menuResult = document.getElementById("menuResult");

    // 점심 메뉴로 초기화 된 배열 생성
    const menu = ["돈까스", "김치볶음밥", "샌드위치", "순두부",
                  "알리오올리오", "페퍼로니피자", "소맥", "짜파구리",
                  "오리", "뇨끼", "파전"]; // 길이 11

    // menu 배열 index 범위 내에서 난수 생성
    const randomNumber = Math.floor(Math.random() * menu.length);
    // Math.floor() 이용 시 소수점 이하가 버려져 정수 범위만 출력
    // 0이상 10 이하 난수 생성

    // 난수 번째 index 요소값을 화면에 출력
    menuResult.innerText = menu[randomNumber];

요소 접근 방법

DOM (Document Object Model : 문서 객체 모델)

  • 웹 문서(HTML)의 모든 요소를 객체 형식으로 표현한 것.
    (HTML 요소 == JS에서 객체라고 부름)

-> 문서 내 특정 요소에 접근 가능
+ 요소(객체)에 속성 값을 세팅 또는 얻어올 수 있다.
document.getElememtById("id속성값");
document.getElementByClassName("class속성값");

DOM을 이용한 요소 접근하기

  1. id로 접근하기 : document.getElementById("id속성값");
    -> 아이디가 일치하는 요소(객체)를 얻어옴
  1. class로 접근하기 : document.getElementsByClassName("class속성값");
    -> 클래스가 일치하는 모든 요소를 얻어와 배열 형태로 반환
  1. name으로 접근하기 : document.getElementsByName("name속성값");
    -> name이 일치하는 모든 요소를 얻어와 배열(NodeList, 유사배열) 형태로 반환
  1. tag로 접근하기 : document.getElementsByTagName("tag명");
    -> 태그가 일치하는 모든 요소를 얻어와 배열 형태로 반환
  1. CSS 선택자로 접근하기
    1) document.querySelector("CSS 선택자");
    -> 선택자가 선택한 요소 중 첫번째 요소를 반환
    2) document.querySelectorAll("CSS 선택자");
    -> 선택한 요소 모두를 배열(NodeList, 유사배열) 형태로 반환

유사배열이란 ?
배열처럼 index, length를 가지고 있으나, 배열 전용 기능(메서드)를 제공하지 않음.
pop(), push(), map(), filter() 등..
HTMLCollection, NodeList는 유사 배열.

HTMLCollection : 동적 Collection
-> DOM 변경 시 자동 업데이트 됨.
-> getElementsByTagName(), getElementsByClassName()

NodeList : 정적 Collection
-> DOM 변경과 무관
-> getElementsByName(), querySelectorAll()

class를 이용한 요소(DOM 객체) 접근하기

  <button onclick="classTest()">배경색 변경</button>
  <div class="cls-test"></div>
  <div class="cls-test"></div>
  <div class="cls-test"></div>
# CSS
.cls-test {
  width: 400px;
  height: 150px;
  border: 1px solid black;
}
# JS

// class 접근 테스트
function classTest() {
  const divs = document.getElementsByClassName("cls-test");

  console.log(divs);

  // divs 0, 1, 2 째 요소에 각각 배경색 변경하기
  divs[0].style.backgroundColor = "rgb(114,203,80)";
  divs[1].style.backgroundColor = "blue";
  divs[2].style.backgroundColor = "deepPink";
}

태그명으로 요소 접근하기

  <ul>
    <li>#ffbe0b</li>
    <li>#fb5607</li>
    <li>#ff006e</li>
    <li>#8338ec</li>
    <li>#3a86ff</li>
  </ul>
  <button onclick="tagNameTest()">배경색 변경</button>
# JS
// 태그명으로 요소 접근하기
function tagNameTest() {

  const tagList = document.getElementsByTagName("li");

  console.log(tagList);

  for(let i = 0; i < tagList.length; i++) {

    console.log(tagList[i].innerText);

    tagList[i].style.backgroundColor = tagList[i].innerText;
  }
}

name으로 요소 접근하기

  • name 속성은 input 또는 input 관련 태그만 기본 속성으로 가지고 있다.
  <table>
    <tr>
      <td>
        <input type="checkbox" name="hobby" id="game" value="게임">
        <label for="game">게임</label>
      </td>
      <td>
        <input type="checkbox" name="hobby" id="music" value="음악감상">
        <label for="music">음악감상</label>
      </td>
      <td>
        <input type="checkbox" name="hobby" id="movie" value="영화감상">
        <label for="movie">영화감상</label>
      </td>
    </tr>

    <tr>
      <td>
        <input type="checkbox" name="hobby" id="coding" value="코딩">
        <label for="coding">코딩</label>
      </td>
      <td>
        <input type="checkbox" name="hobby" id="exercise" value="운동">
        <label for="exercise">운동</label>
      </td>
      <td>
        <input type="checkbox" name="hobby" id="book" value="독서">
        <label for="book">독서</label>
      </td>
    </tr>
  </table>

  <div id="name-div"></div>

  <button onclick="nameTest()">선택된 취미만 출력하기</button>
# CSS
#name-div {
  width: 300px;
  height: 100px;
  border: 1px solid black;
}
# JS
// name으로 요소 접근하기
function nameTest() {
  // name 속성값이 hobby인 요소를 모두 얻어와 변수에 저장
  const hobbyList = document.getElementsByName("hobby");

  console.log(hobbyList);

  let str = ""; // 체크된 값 누적할 문자열
  let count = 0; // 체크된 수 카운트

  for(let i = 0; i < hobbyList.length; i++ ){

    // checkbox, radio 전용 속성 (.checked)

    // input요소.checked 
    // -> 요소가 체크되어있다면 true, 아니면 false 반환
    // input요소.checked = true; -> 해당 요소를 체크하겠다.
    // input요소.checked = false; -> 해당 요소를 체크 해제하겠다.

    if(hobbyList[i].checked) {
      str += hobbyList[i].value + " ";
      count++;
    }
  }

  // #name-div 요소에 내용으로 결과 출력
  document.getElementById("name-div").innerHTML
    = `${str} <br><br>선택된 취미 개수 : ${count}`;

    // 요소.innerHTML 
    // HTML 태그를 포함하여 문자열 등을 실제 HTML 요소로 해석함

    // 요소.innerText
    // 텍스트 내용만 요소 콘텐트 내부에 출력함.(HTML 코드로 해석 X)
}

CSS 선택자로 요소 접근하기

  <div target-div="css-div">
    <div>test1</div>
    <div>test2</div>
  </div>

  <button onclick="cssTest()">css 선택자로 요소 접근하기</button>
# CSS
[target-div="css-div"] {
  width: 200px;
  height: 200px;
  border: 1px solid black;
}

[target-div="css-div"] > div {
  height: 50%;
}

[target-div="css-div"] > div:first-child {
  background-color: pink;
}

[target-div="css-div"] > div:last-child {
  background-color: yellow;
}
# JS
function cssTest() {

  // target-div 속성값이 "css-div" 요소에 접근
  const container = document.querySelector("[target-div='css-div']");

  // 요소의 테두리 변경
  container.style.border = "10px solid red";

  // 첫번째 자식 div 접근해서
  // 내용을 "CSS 선택자로 선택해서 값 변경됨" 변경해보기
  const div1 = document.querySelector("[target-div='css-div'] > div");
  div1.innerText = "CSS 선택자로 선택해서 값 변경됨";

  const div2 = document.querySelector("[target-div='css-div'] > div:last-child");
  div2.innerText = "첫번째 요소가 아니면 querySelector() 특징 활용 못함";

  // 모든 자식 div 한 번에 선택(배열)
  const divList = document.querySelectorAll("[target-div='css-div'] > div");

  console.log(divList);

  // index를 이용해서 요소 하나씩 접근
  divList[0].style.fontFamily = "궁서";
  divList[1].style.fontSize = "20px";

  for(let i=0; i < divList.length; i++) {
    divList[i].onclick = function() {
      alert(`${i} 번째 요소 입니다!`);
    }
  }
}

카카오톡 모양의 채팅화면 만들기

  <div class="chatting">
    <div id="chatting-bg">
      <p><span>입력되는 채팅 출력</span></p>
      <p><span>입력되는 채팅 출력</span></p>
      <p><span>입력되는 채팅 출력</span></p>
    </div>

    <div id="chatting-input">
      <input type="text" id="user-input">
      <button onclick="readValue()">입력</button>
    </div>
  </div>
# CSS
/* 카카오톡 채팅 화면 만들기 */

.chatting, .chatting * {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
}

/* 전체 감싸는 요소 */
.chatting {
  width: 360px;
  border: 1px solid black;
  margin: 50px 20px;
}

/* 채팅 출력 부분 */
#chatting-bg {
  background-color: rgb(178, 199, 217);
  width: 100%;
  height: 400px;

  /* overflow : 내부 내용이 감싸는 요소를 넘었을 때 처리하는 속성 */
  /* auto : 넘치기 전 -> 변화없음 , 넘친 후 -> 스크롤 발생 */
  /* hidden : 넘친 부분을 안보이게끔 처리함 */
  overflow: auto;
}

/* 채팅 내용 */
#chatting-bg > p {
  margin: 20px 10px;
  text-align: right;
}

#chatting-bg > p > span {
  background-color: rgb(254, 234, 51);
  padding: 5px;
  border-radius: 5px;
}

/* 입력 부분 */
#chatting-input {
  width: 100%;
  display: flex;
  height: 22px;
}

#chatting-input > input {
  height: 100%;
  width: 90%;
  outline: 0;
  padding-left: 5px;
}

#chatting-input > button {
  height: 100%;
  width: 10%;
}
# JS
// 카카오톡 채팅 화면 만들기
function readValue() {

  // 채팅이 출력되는 배경 요소
  const bg = document.querySelector("#chatting-bg");

  // 채팅 내용 입력 input 요소
  const input = document.querySelector("#user-input");

  // 입력된 값이 없을 경우
  // 1) 진짜 안적음
  // 2) 공백만 적음

  // 문자열.trim() : 문자열 좌우 공백 제거
  if(input.value.trim().length == 0) {
    alert('채팅 내용을 입력해주세요');

    input.value = ""; // 이전 input에 작성된 값 삭제

    input.focus(); // input에 커서 활성화

    return; // 아래 수행 X , 현재 수행중인 함수 종료
  } 

  bg.innerHTML += `<p><span>${input.value}</span></p>`;

  bg.scrollTop = bg.scrollHeight;
  // bg.scrollTop : 현재 스크롤 위치
  // (스크롤이 현재 얼마만큼 내려와있는지를 나타냄)

  // bg.scrollHeight : bg의 스크롤 전체 높이
  // (스크롤바를 이용해 스크롤 할 수 있는 전체 높이)

  //console.log(bg.scrollTop);
  //console.log(bg.scrollHeight);

  input.value = "";
  input.focus();
}

/*
아이디가 user-input인 input요소에서
키가 올라오는 동작이 발생했을 때(감지되었을때)
올라온 키가 "Enter" 키 이면 readValue() 함수를 호출
*/

// keydown : 키가 눌러졌을 때 (+ 꾹 누르고 있으면 계속 인식됨)
// keyup : 눌러지던 키가 떼어졌을 때(1회만 인식)

document.querySelector("#user-input")
.addEventListener("keyup", function(e) {

  // e : 이벤트 객체 (발생한 이벤트 정보를 담고있는 객체)
  console.log(e);

  if(e.key == "Enter") { // 엔터가 눌러지고 떼어졌을 때
    readValue();
  }
});

이벤트

동작, 행위
-> 브라우저에서 할 수 있는 동작

ex) click, keyup, keydown, keypress, mouseover, mouseon, mouseout,
mouseleave, drag, change, submit...

* 이벤트 리스너 (Event Listener)
-> 브라우저에서 이벤트가 감지될 때까지 대기하다가 감지가 되었을 때
연결된 기능(함수)을 수행하는 것.

  • 이벤트 리스너는 "on이벤트명" 형식으로 작성됨
    ex) onclick, onchange, onsubmit, onkeyup ...

* 이벤트 핸들러 (Event Handler)
-> 이벤트 리스너에 연결된 기능(함수)으로
이벤트가 감지되었을 때 수행할 내용을 작성한 함수(function)

인라인 이벤트 모델 (Inline)

  • HTML 요소에 이벤트리스터='이벤트핸들러' 형식을 작성하는 방법

  • 하나의 요소에 동일한 이벤트 핸들러를 중복 작성 X

* 최근에는 사용을 많이 하지는 않지만 종종 사용됨
* 인라인 이벤트 모델 작성 시 this -> 이벤트가 발생한 현재 요소

  <button onclick="check1(this)" style="background-color: yellow;">
    인라인 이벤트 모델 확인
  </button>
# JS

/* 인라인 이벤트 모델 확인 */
function check1(btn) {
  console.log(btn);
  // 매개변수 btn == 클릭한 버튼(this)

  // 현재 버튼의 배경색을 얻어와 저장
  const bgColor = btn.style.backgroundColor;

  // 버튼이 클릭 될 때마다 pink <-> yellow 변경
  if(bgColor == "yellow") {
    btn.style.backgroundColor = "pink";
  } else {
    btn.style.backgroundColor = "yellow";
  }
}

고전 이벤트 모델

  • HTML 요소에 이벤트 관련 코드를 작성하지 않고
    JS에서 DOM 객체에 직접 이벤트 관련 코드를 작성하는 방법.

  • 하나의 요소에 동일한 이벤트 핸들러를 중복 작성 X

  <button id="test1-1">고전 이벤트 모델 확인</button>
  <button id="test1-2">고전 이벤트 모델 제거</button>
  <button id="test1-3">고전 이벤트 모델 단점</button>
# JS

// 고전 이벤트 모델 확인

// 아이디가 test1-1 요소를 얻어와 test1a 변수에 저장
const test1a = document.querySelector("#test1-1");

// ** 고전 이벤트 모델 작성법 **
// 요소.이벤트리스너 = 이벤트핸들러

test1a.onclick = function() {
  alert("고전 이벤트 모델 확인 버튼 클릭됨");
}

// 고전 이벤트 모델 제거

// #test1-2 버튼 클릭 시
// #test1-1 의 onclick 이벤트리스너의 이벤트 핸들러 제거하기
document.querySelector("#test1-2").onclick = function() {

  // 기존 onclick 의 이벤트핸들러(함수)를
  // null 로 덮어씌움 (이벤트제거)
  test1a.onclick = null;
  alert("이벤트 제거됨");
}

// 고전 이벤트 모델 단점

// #test1-3 요소를 얻어와 test1c 변수에 저장
const test1c = document.querySelector("#test1-3");

// #test1-3 요소가 클릭되었을 때 배경색 빨간색으로 변경
test1c.onclick = function() {
  test1c.style.backgroundColor = "red";
}

// 시간이 지난 뒤

test1c.onclick = function() {
  test1c.style.color = "white";
}

// -> onclick에 저장된 값이 덮어씌워지면서
// 이전 코드(배경색 red)가 사라지는 문제 발생

표준 이벤트 모델 (요소.addEventListener())

  • w3c (웹 표준 재정 단체)에서 공식적으로 지정한 이벤트 모델

  • 특징 : 한 요소에 중복되는 이벤트 리스너를 만들어 여러 이벤트 핸들러를 추가할 수 있다.
    -> 고전 이벤트 모델 단점 해결

 <!-- 클릭할 수록 투명해지게 + 클릭한 횟수 count -->
  <div id="test2">클릭!!!</div>
# CSS

#test2 {
  width: 100px;
  height: 100px;
  border: 1px solid black;
  background-color: green;
}
# JS

// 표준 이벤트 모델 확인
const test2 = document.querySelector("#test2");

// *** 표준 이벤트 모델 작성법 ***
// 요소.addEventListener("이벤트종류", 이벤트핸들러(함수));

test2.addEventListener("click", function() {

  // 투명도 1 (불투명) -> 0 (투명) 0.1씩 감소

  // 현재 #test2 의 투명도 확인
  let curr = test2.style.opacity;

  console.log(curr);

  // 맨처음에는 투명도 "" -> 1 대입
  if(curr == '') {
    test2.style.opacity = 1;
    curr = 1;
  }

  // 투명도 0.1 감소
  test2.style.opacity = curr - 0.1;

  if(test2.style.opacity == 0) { // 완전히 투명해졌다면
    test2.style.opacity = 1; // 다시 불투평하게 바꿔라
  }
});

// #test2 요소를 클릭하면 클릭 횟수 카운트
let count = 0;

test2.addEventListener("click", function() {

  count++; // 카운트 1 증가

  // 표준 이벤트 모델의 이벤트 핸들러 내부에서 this
  // == 이벤트가 발생한 요소
  this.innerText = count;
});

연습문제

입력한 색상으로 배경색 변경하기

  <div class="container3">
    <div id="box3"></div>
    <input type="text" id="input3" placeholder="색상 입력">
  </div>
# CSS

.container3 {
  width: 200px;
  border: 1px solid black;
  display: flex;
  flex-direction: column;
  padding: 5px;
}

#box3 {
  box-sizing: border-box;
  height: 200px;
  border: 1px solid black;

  transition-duration: 0.5s;
}

.container3 * {
  margin-bottom: 5px;
}
# JS

const input3 = document.querySelector("#input3");
const box3 = document.querySelector("#box3");

input3.addEventListener("keyup", function(e) {

  if(e.key == "Enter") {
    box3.style.backgroundColor = input3.value;
  }
});

box3.addEventListener("click", function(e) {

  // e.target : 이벤트가 발생한 대상 요소 == this

  alert(`배경색 : ${e.target.style.backgroundColor}`);
})

profile
인생은 변수

0개의 댓글