본문 바로가기
JavaScript/JavaScript

Javascript) this 용법, .parentElement, .className, .classList

by 박채니 2022. 5. 18.

안녕하세요, 코린이의 코딩 학습기 채니 입니다.

 

개인 포스팅용으로 내용에 오류 및 잘못된 정보가 있을 수 있습니다.


this 용법 1)

전역에서 this는 window 객체를 가리킴

<script>
console.log(this);
</script>

 

this 용법 2)

태그의 inline event 속성 안의 this는 현재 tag 객체를 가리킴

<input type="checkbox" id="checkAll" onclick="checkAllOrNone(this);">
function checkAllOrNone(obj) {
    console.log(obj);
}

윈도우 객체가 아닌 넘겨준 tag (checkbox)의 객체가 전달된 것을 확인할 수 있습니다.

 


전체 선택/해제

HTML 코드

<body>
    <h1>클래스 제어하기</h1>

    <table>
        <thead>
            <hr> 
                <th colspan="5">
                    <h2>수강신청</h2>
                </th>
            </hr>
        </thead>
        <tbody>
            <tr>
                <th colspan="5">
                    <input type="checkbox" id="checkAll" onclick="checkAllOrNone(this);">
                    <label for="checkAll">전체선택/해제</label>
                </th>
            </tr>
            <tr>
                <td class="gungseo"><input type="checkbox" name="subject" id="subject1"><label for="subject1">국어</label></td>
                <td class="gungseo"><input type="checkbox" name="subject" id="subject2"><label for="subject2">영어</label></td>
                <td class="gungseo"><input type="checkbox" name="subject" id="subject3"><label for="subject3">수학</label></td>
                <td class="gungseo"><input type="checkbox" name="subject" id="subject4"><label for="subject4">사회</label></td>
                <td class="gungseo"><input type="checkbox" name="subject" id="subject5"><label for="subject5">과학</label></td>
            </tr>
        </tbody>
    </table>
</body>

 

CSS 코드

<style>
    table {
        border: 1px solid black;
        border-collapse: collapse;
        width: 500px;
        margin: 10px auto;
    }

    th, td {
        text-align: center;
        border: 1px solid black;
        padding: 5px;
    }
    .gungseo {
        font-family: 궁서, cursive;
    }
</style>

 

Javascript 코드

function checkAllOrNone(obj) {
    const subjects = document.querySelectorAll("[name=subject]");

    for(let i = 0; i < subjects.length; i++) {
        subjects[i].checked = obj.checked;  // checked처리
    }
}

전체선택/해제 버튼을 누르면 각 checkbox가 전체 선택 혹은 해제 되게 하였습니다.

(넘겨준 this 객체를 이용)

 

 

checkbox가 모두 선택될 때 또한 전체선택/해제 버튼 활성화

→ 각 checkbox 중 하나라도 해제 되면 전체선택/해제 버튼 또한 비활성화 하게 만들어보겠습니다.

 

HTML 코드

<tr>
    <td class="gungseo"><input type="checkbox" name="subject" onchange="checkSubject()"; id="subject1"><label for="subject1">국어</label></td>
    <td class="gungseo"><input type="checkbox" name="subject" onchange="checkSubject()"; id="subject2"><label for="subject2">영어</label></td>
    <td class="gungseo"><input type="checkbox" name="subject" onchange="checkSubject()"; id="subject3"><label for="subject3">수학</label></td>
    <td class="gungseo"><input type="checkbox" name="subject" onchange="checkSubject()"; id="subject4"><label for="subject4">사회</label></td>
    <td class="gungseo"><input type="checkbox" name="subject" onchange="checkSubject()"; id="subject5"><label for="subject5">과학</label></td>
</tr>

각 체크 박스에 onchange가 발생하면 checkSubject() 함수가 실행되도록 하였습니다.

 

Javascript 코드

function checkSubject() {
    const subjects = document.querySelectorAll("[name=subject]");	// 체크박스
    const checkedSubject = document.querySelectorAll("[name=subject]:checked");	//체크된 박스
	
    console.log(subjects, checkedSubject);
    
    checkAll.checked = (subjects.length == checkedSubject.length);
}

name값이 subject인 객체들의 수와 name값이 subject인 객체 중 checked 속성이 적용된 수를 비교하여 해당 수가 같다면, 

즉 name=subject를 가진 객체(전체객체)와 checked가 된 객체의 수를 비교하여 동일하다면 checkAll의 checked 박스가 활성화 되도록 하였습니다.

 

 

이번엔 선택된 박스들의 background-color를 변경해보겠습니다.

 

HTML 코드

<td class="gungseo"><input type="checkbox" name="subject" onchange="checkSubject(this)"; id="subject1"><label for="subject1">국어</label></td>
<td class="gungseo"><input type="checkbox" name="subject" onchange="checkSubject(this)"; id="subject2"><label for="subject2">영어</label></td>
<td class="gungseo"><input type="checkbox" name="subject" onchange="checkSubject(this)"; id="subject3"><label for="subject3">수학</label></td>
<td class="gungseo"><input type="checkbox" name="subject" onchange="checkSubject(this)"; id="subject4"><label for="subject4">사회</label></td>
<td class="gungseo"><input type="checkbox" name="subject" onchange="checkSubject(this)"; id="subject5"><label for="subject5">과학</label></td>

어떤 chekcedbox가 활성화 되었는 지 알아야하기 때문에 checkSubject함수에 (this)를 넘겨줍니다.

 

Javascript 코드

function checkSubject(subject) {
    // 부모 td .on처리
    console.log(subject);
    console.log(subject.parentElement);

    // 전체 체크 박스 처리
    const subjects = document.querySelectorAll("[name=subject]");
    const checkedSubject = document.querySelectorAll("[name=subject]:checked");
    console.log(subjects, checkedSubject);
    checkAll.checked = (subjects.length == checkedSubject.length);
}

체크한 속성의 객체가 잘 넘어오는 것을 확인하였고, <td>는 <input>태그의 부모 객체이므로, .parentElement를 통해 부모인 <td>를 가져옵니다.

 

function checkSubject(subject) {
    // 부모 td .on처리
    // console.log(subject);
    // console.log(subject.parentElement);
    const td = subject.parentElement;
    td.className = subject.checked ? "gungseo on" : "gungseo";

    // 전체 체크 박스 처리
    const subjects = document.querySelectorAll("[name=subject]");
    const checkedSubject = document.querySelectorAll("[name=subject]:checked");
    console.log(subjects, checkedSubject);
    checkAll.checked = (subjects.length == checkedSubject.length);
}

.className로 className을 변경해주는데, subject가 checked라면 "gungseo on"으로, unchecked라면 기존 클래스인 "gungseo"가 적용되도록 하였습니다.

여기서 className을 "on" : ""으로 주게 된다면 className이 "on" 혹은 ""으로 변경되므로 기존 클래스인 "gungseo"클래스가 날라가게 됩니다.

 

"on" 혹은 ""으로 하게 되면 아래처럼 className이 "on"으로 설정! (문자열로 관리되기 때문)

 

기존 className도 같이 기재해줘야 하는 번거로움이 있습니다.

 

해결방법! classList 객체 이용

console.dir(td.classList);

className을 공백기준으로 잘라내어 배열처럼 관리하기 때문에 기존 class에 대한 신경을 안 써도 됩니다.

 

코드 중복 제거를 위해 함수를 하나 생성하겠습니다.

function handleTdClass(subject) {
    const td = subject.parentElement;

    if(subject.checked) 
        td.classList.add("on");
    else   
        td.classList.remove("on");
}

add, remove를 통해서 "on"클래스를 추가/제거할 수 있습니다.

 

이 외에 toggle(class), contains(class):boolean 등을 자주 사용합니다.

- toggle : 있으면 추가, 없으면 제거

- contains : 특정 클래스는 가지고 있는 지, 없는 지 리턴