JavaScript

9. Javascript DOM DOMContentLoaded

char1ey 2022. 11. 11. 08:40
목차
1. DOMContentLoaded

  1.1. <script>를 아래 부분에 두었던 이유
  1.2. DOMContentLoaded
    1.2.1. DOMContentLoaded 사용방법
  1.3. <script>의 위치에 따른 장.단점
    1.3.1. <script>가 위에 있을 경우
    1.3.2. <script>가 아래에 있을 경우
    1.3.3. 두 방법 중 더 좋은 것은?
2. <form>엘리먼트와 메서드

  2.1. <form>과 관련된 속성들
    2.1.1. <input>
    2.1.2. <button>
    2.1.3. <form>
  2.2. e.preventDefault
3. Javascript로 HTML Element 생성하기

  3.1 document.createElement()
    3.1.1 생성 Element 위치 정하는 방법: append()

 


1. DOMContentLoaded

 

1.1 <script>를 아래 부분에 두었던 이유

 

  • HTML은 위에서 아래로 코드를 해석해 나간다. 즉, <script>를 읽고 <body>부분으로 내려간다. 즉, JS를 읽는 시점에 <body>가 없기 때문에 효과를 줄 수 없었다. 이런 이유로 <body>의 가장 아래부분에 <script>를 위치 시켰다.
  • 아래의 예시를 보면, <script>가 제일 먼저 읽혀 <div>를 읽기전에 아래의 JS부분을 먼저 읽어 "null"값이 출력된다.
<script src="./"></script> <!-- <div> 태그보다 먼저 읽힌다. -->
<div class="box"></div>
const box = document.querySelector(".box") // class = "box"를 선택하는 변수
console.log(box) // null

 

1.2 DOMContentLoaded

 

위의 1.1 에서 발생했던 문제점을 해소하기 위해서, "DOMContentLoaded"라는 이벤트에 대해 알아보자.

  • <body> 영역의 해석이 끝나는 시점을  이벤트의 발생으로 한다.
  • <script>를 윗쪽에 위치시키더라도, 아랫쪽에 위치시킨 것처럼 JS의 효과를 적용시킬 수 있다.

1.2.1 DOMContentLoaded 사용방법

function init() {
    const box = document.querySelector(".box")

    console.log(box) // <div class = "box"></div>
    console.log("hello world!") // "hello world!"
}

document.addEventListener("DOMContentLoaded", init) // "DOMContentLoaded"발생 시 init 시작

<script>를 윗쪽에 위치시켜 "DOMContentLoaded" 이벤트를 추가하여, init함수를 시작하게 한다.

<body>의 로딩이 끝나는 순간 init함수 안의 코드를 읽어 나가기 때문에 정상적으로 JS를 적용시킬 수 있다.

 

 

1.3 <script> 위치에 따른 장, 단점

 

위, 아래 중 어느 쪽으로 <script>위치를 주는 게 더 좋은걸까?

 

1.3.1 <script>가 위에 있을 경우

 

- JS를 읽고나서, HTML의 <body>를 읽어나간다.

- JS가 길게 작성되어 있을 경우, JS를 모두 읽고 HTML을 읽기 때문에 로딩시간이 느려질 수 있다.

- 로딩이 끝나는 동시에 JS가 적용된다.

 

1.3.2 <script>가 아래에 있을 경우

 

- HTML의 <body>를 읽고나서 JS를 읽어나간다.

- <body>부분을 먼저 읽어 화면에 렌딩한 후 JS를 적용하기에 로딩시간이 빠르다.

- HTML부터 렌딩되기 때문에 꾸며지지 않은 화면이 먼저 렌더될 수 있다.

 

1.3.3 두 방법 중 더 좋은 것은?

 

- 어느 방법이 더 좋다고 할 수 없고, 개발자의 취향에 따라, 장.단점에 따라 사용법을 선택하면된다.

- 여담으로 사이트의 User들은 평균적으로 로딩이 3초보다 길어지면 사이트를 떠난다고 한다.


2.  <form> 엘리먼트와  메서드

 

  • HTML에서 <form> 엘리먼트는 통신을 위해서 사용된다. 백엔드 측면에서 필수적인 엘리먼트라고 할 수 있다. 그러므로 <form> 엘리먼트 관련 이벤트를 알아둘 필요가 있다.

 

2.1 <form>과 관련된 속성들

 

우선, HTML을 작성해보자.

<form method="get" id="loginForm" action="./">
    <input type="text" id="uid" name="userid" value="char1ey">
    <input type="password" id="upw" name="userpw" value="1234">
    <button type="submit">로그인<button>
<form>

2.1.1 <input>

  • name 속성은 키, value 속성은 값의 형태로 <button type="submit">을 통해 <form method="get">에게 전달해준다.
  • value의 값은 로드시 <input>박스에 미리 입력되어있다.

 

2.1.2 <button>

  • `submit` 속성을 통해 <form method="get"> 속성에 전달시켜준다.

 

2.1.3 <form>

  • `method="get"`을 통해, `submit`의 제출을 받고, `action`에 적힌 링크로 이동하고 url창에 <input>의 `name`과 `value`값을 키와 값의 형태로 나타내준다.

 

 

2.2 e.preventDefault

 

만약, <input>의 내용. 즉, value의 값을 <button type="submit">을 통해 <form>에 전달되기 전에 console.log로 값을 출력하고 싶다면 어떻게 해야할까?

 

HTML 태그들의 기본적인 기능을 JS로 막고 싶을 때 사용할 수 있는 메서드가 있다.

 

잠시, 위의 버튼 클릭시 발생하는 상황과 원하는 과정을 정리해 보자.

  • <button> 클릭 시, `action`속성의 값으로 url이 이동하여 <input>의 name과 value가 전달이 되어 출력된다.

 

  • 이 때, 클릭을 하더라도 이동을 바로 시키고 싶지않다.
  1. HTML의 엘리먼트 기능을 막는다.
  2. 원하는 함수나 로직을 실행한다.
  3. 다시 HTML 엘리먼트의 기능을 실행한다. 

2번의 기능을 하기위해 `e.preventDefault` 메서드를 사용해 보자.

 

`e.preventDefault`는 HTML의 기능의 실행을 막아준다. 막아주기만 한다면, 원하는 대로 기능을 실행 시킬 수가 없기 때문에 원할 때에 다시 실행할 수 있도록 하는 코드가 필요하다. 이렇게 되면 내가 원할 때에 멈추고, 실행할 수 있게 되어 문서를 `내 마음대로 컨트롤` 할 수 있게 된다. 

function submitHandler(e){
    e.preventDefault() // 엘리먼트의 기능을 막아준다.
    e.target.submit() // 해당 엘리먼트를 선택, `submit` 이벤트 선택, 실행
}

document.addEventListener("submit", `함수`)

 

위의 코드를 이용해서 다음을 구현해보자.

- <input> 상자의 값이 비어 있다면, `submit`을 멈추고 <input> 상자 색상을 바꾼다.

- <input> 상자의 값이 채워져 있다면, `submit`을 실행한다.

 

Q) <input>의 내용이 비어있다는 것을 어떻게 알 수 있을까?

A) <input>의 `value`를 통해서 알 수 있다.

 

*구현 1단계*

  1. id가 `uid`인 <input> 가져오기. (단, submitHandler 안에서 선택자(지역변수)를 선언해야한다.)
  2. uid.value를 console.log하여 값을 가져왔는지 확인한다.
function submitHandler(e){
    e.preventDefault() // 엘리먼트의 기능을 막아준다.

    const uid = document.querySelector("#uid") // id="uid"를 선택하고 변수에 담는다.
    const upw = document.querySelector("#upw") // id="upw"를 선택하고 변수에 담는다.

    console.log(uid.value) // <input id="uid"> 상자의 value값 출력
    console.log(upw.value) // <input id="upw"> 상자의 value값 출력
   
    e.target.submit() // 해당 엘리먼트를 선택, `submit` 이벤트 선택
}

*구현 2단계*

  1. uid와 upw의 값이 있다면, `submit`실행.
  2. uid와 upw의 값이 없다면, 경고창실행.
  3. 아이디나 비밀번호가 비어있을 경우, 상황에 맞게 <input> 아래에 글자를 띄운다.
function submitHandler(e){
    e.preventDefault() // 엘리먼트의 기능을 막아준다.

    const uid = document.querySelector("#uid") // id="uid"를 선택하고 변수에 담는다.
    const upw = document.querySelector("#upw") // id="upw"를 선택하고 변수에 담는다.
    const please = document.querySelector("#loginForm > h3") // h3를 선택하고 변수에 담는다.

    if(uid.value === "" && upw.value !== ""){
        alert("아이디를 입력해주세요.") // 경고창 띄우기
        upw.style = "" // <input> 색상되돌리기
        uid.style = "background: red;" // <input> 색상변경
        please.style = "display: block; color: red;"// <h3> 보이게 하기
        please.innerHTML = "아이디를 입력해주세요!" // 경고문구 넣기

    } else if(uid.value !== "" && upw.value === ""){
        alert("비밀번호를 입력해주세요.") // 경고창 띄우기
        uid.style = ""// <input> 색상되돌리기
        upw.style = "background: red;" // <input> 색상변경
        please.style = "display: block; color: red;"// <h3> 보이게 하기
        please.innerHTML = "비밀번호를 입력해주세요!" // 경고문구 넣기

    } else if(uid.value === "" && upw.value ===""){
        alert("아이디와 비밀번호를 입력해주세요.") // 경고창 띄우기
        uid.style = "background: red;" // <input> 색상변경
        upw.style = "background: red;" // <input> 색상변경
        please.style = "display: block; color: red;" // <h3> 보이게 하기
        please.innerHTML = "아이디와 비밀번호를 입력해주세요!" // 경고문구 넣기

    } else {
        e.target.submit() // 해당 엘리먼트를 선택, `submit` 이벤트 선택
        uid.style = "" // <input> 색상되돌리기
        upw.style = "" // <input> 색상되돌리기
        uid.value = "" // <input> 초기화시키기
        upw.value = "" // <input> 초기화시키기
    }

}

3. Javascript로 HTML Element 생성하기

 

- Javascript에서 HTML Element를 생성하여 넣는 법을 알아보자.

 

*구현 목표*

- <input> 박스 아래로 입력한 값을 띄운다.

 

 

3.1 document.createElement()

  • 엘리먼트를 생성시키는 DOM 메서드이다.
  • 단, 생성은 되지만 위치는 따로 정해주어야 한다.

3.1.1 생성 Element 위치 정하는 방법: append()

  • 메서드 `append`를 사용하여 자식태그에 해당 엘리먼트를 넣어준다.
  • element.append()
  • 부모 엘리먼트 객체를 적고 .append 메서드의 인자값으로 자식 태그(생성된)를 적어준다.

*구현 1단계*

  1. HTML에 <ul>을 생성하여 id="userList"를 부여.
  2. <ul>안에 <li>를 생성하여 넣는다.
    const userlist = document.querySelector("#userList") // id="userList"를 선택하고 변수선언

    const liElement = document.createElement("li") // <li>를 생성하는 변수선언

    userlist.append(liElement)

 

 

*구현 2단계*

  1. 언제 실행이 되야하는지, 무엇을 가져올 것인지 정해야한다.
  2. (언제) id와 pw 둘 다 채워져있을 때(if조건)
  3. (무엇을) id와 pw의 내용을 가져온다. (value값과 innerHTML)
const userlist = document.querySelector("#userList") // id="userList"를 선택하고 변수선언

const liElement = document.createElement("li") // <li>를 생성하는 변수선언

userlist.append(liElement)

if(uid.value === "" && upw.value !== ""){
    alert("아이디를 입력해주세요.")

} else if(uid.value !== "" && upw.value === ""){
    alert("비밀번호를 입력해주세요.")
    
    } else if(uid.value === "" && upw.value ===""){
    alert("아이디와 비밀번호를 입력해주세요.")

} else {
    userlist.append(liElement)
    const liElement1 = document.querySelector("#userList > li")
    liElement1.innerHTML = uid.value + " " + upw.value
}