ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • DOM - 요소노드에 대한 접근
    프론트엔드/DOM 2020. 10. 7. 01:32

    'DOM'은 'HTML' 문서의 요소와 내용들을 객체화시킨 것이다.

     

    그리고 이러한 객체에 접근하여 컨트롤을 해줄 수 있다.

     

    그리고 이때 접근하기 쉽게 메서드와 프로퍼티가 제공된다.

     

    여기서는 문서의 요소(Element) 노드에 어떻게하면 접근할 수 있는지를 알아본다.

    단일 요소에 접근하기

    1. getElementById()

     

    대략 해석해서 쓰자면 다음과 같다.

     

    '파라미터로 주어진 문자열과 동일한 id값를 통해 요소를 얻을 수 있게 한다.'

     

    'getElementById()'에 제공한 문자열과 동일한 'id' 속성을 가진 요소를 HTML 문서에서 찾아준다.

     

    그리고 이 'id' 속성을 가진 'Element' 객체를 반환한다.

     

    즉 해당 요소를 이용할 수 있게 도와준다는 말이다.

     

    <body>
    
        <p id="test"> ID테스트입니다. </p>
    
        <script>
            document.getElementById('test').innerHTML = "아이디 속성으로 접근합니다.";
            // 해당 코드를 실행하면
            // 'test'를 'id'로 가진 <p> 태그의 내용이
            // "아이디 속성으로 접근합니다"로 변경된다.
    
        </script>
    </body>

     

    코드는 위와 같다.

     

    위와 같이 메서드를 안에 문자열을 넣어주면 해당 문자열과 동일한 'id'값을 가진 요소의 객체를 반환한다.

     

    <body>
    
        <p id="test"> ID테스트입니다. </p>
        
        <p id="test"> ID테스트입니다.2 </p>
    
        <script>
            document.getElementById('test').innerHTML = "아이디 속성으로 접근합니다.";
            // 해당 코드를 실행하면
            // 첫번째 'test'를 'id'로 가진 <p> 태그의 내용이
            // "아이디 속성으로 접근합니다"로 변경된다.
    
        </script>
    </body>

     

    참고로 해당 메서드는 'html' 문서 내에서 단 하나만 존재해야하는 'id'값에 접근하는 것이다.

     

    그래서 메서드의 이름도 자세히 보면 다른 요소 객체 반환 메서드와 달리 'getElement'다.

     

    즉 여러개가 아닌 하나의 요소만 얻게해준다는 것이다.

     

    그리고 위 코드처럼 같은 'id'값을 두개를 써도 둘 중 처음 나오는 'id'값의 요소 객체만을 반환한다.

    복수 요소에 접근하기

    복수 요소에 접근하는 대략 세가지 메서드가 존재한다.

     

    ● getElementsByTagName

     

    ● getElementsByClassName

     

    ● querySelectorAll

     

    세 가지 메서드 모두 단일 요소를 선택하는 'getElementById'와 다르다.

     

    메서드 이름에 'All'이나 'Elements'와 같이 복수 요소를 선택할 수 있다는 뜻의 단어를 내포하고 있다.

     

    세가지 메서드를 이용하면 'HTML' 문서에서 내가 원하는 모든 요소의 객체를 반환해준다는 것이다.

     

    앞서 'getElementById'는 동일 'id' 값이 아무리 많아도 그중 첫 번째 요소만 반환했다.

     

    하지만 위의 세 가지 메서드는 메서드의 조건에 해당하는 모든 요소의 객체를 반환한다.

     

    각 메서드 별로 살펴보자.

    1. getElementsByTagName()

     

    대략 해석해서 쓰자면 다음과 같다.

     

    '파라미터로 주어진 태그명과 같은 복수의 태그 요소들의 객체를 반환한다.'

     

    즉 'getElementsByTagName'를 쓰면 같은 태그 네임을 가진 복수의 요소의 객체를 반환한다는 것.

     

    코드로 보자.

     

    <body>
        <p> 일반 문장입니다. </p>
        <p> 일반 문장입니다. </p>
        <p> 일반 문장입니다. </p>
    
        <script>
    
            document.getElementsByTagName('p').innerHTML = "태그네임으로 접근합니다";
    
        </script>
    </body>

     

    위 코드를 실행하면 어떻게 될까? 결론부터 말하면 아무런 변화가 없다.

     

    얼핏보면 <P> 태그를 가진 모든 요소의 내용이 "태그네임으로 접근합니다"로 바뀔 것 같다.

     

    하지만 그렇지 않다.

     

    'getElementsByTagName'는 문서 내에 있는 조건에 맞는 요소의 객체를 모두 반환한다고 했다.

     

    하지만 요소의 객체를 모두 반환한다고해서 모든 <p> 태그의 내용을 바꿔버린다면 문제가 생길 것이다.

     

    만약 세 개의 <p> 태그 중 마지막 <p> 태그만 바꾸고 싶다면 이 메서드를 사용할 수 없기 때문이다.

     

    그래서 'getElementsByTagName' 뿐 아니라 다른 복수 요소에 접근하는 모든 메서드는

     

    조건에 맞는 객체를 유사 배열이라는 객체라는 배열과 유사한 형태로 만들어 객체를 반환한다.

     

    우선 위 코드에서 쓴 'document.getElementsByTagName('p')' 를 'console.log'로 출력해보자.

     

    <body>
        <p> 일반 문장입니다. </p>
        <p> 일반 문장입니다. </p>
        <p> 일반 문장입니다. </p>
    
        <script>
    
            console.log(document.getElementsByTagName('p'));
    
        </script>
    </body>

     

     

    위 코드를 실행한 결과는 아래와 같다.

     

     

    어딘지 우리가 알고있는 배열과 비슷하다. 실제로 사용법도 동일하다.

     

    <body>
        <p> 일반 문장입니다 1. </p>
        <p> 일반 문장입니다 2. </p>
        <p> 일반 문장입니다 3. </p>
    
        <script>
    
            document.getElementsByTagName('p')[0].innerHTML = "유사배열 1"
            document.getElementsByTagName('p')[1].innerHTML = "유사배열 2"
            document.getElementsByTagName('p')[2].innerHTML = "유사배열 3"
            
            // 메서드 뒤에 배열처럼 []로 인덱스를 선택해줬다.
            
            // 이 상태로 코드를 실행하면
            // <p> 태그들은 각각 
            // "유사배열 1", "유사배열 2", "유사배열 3"으로 바뀐다.
    
        </script>
    </body>

     

    만약 복수의 요소 중 한 개만 선택해서 사용하고 싶다면 위의 코드처럼 하면된다.

     

    배열 쓰듯이 인덱스 넘버를 지정해주면 거기에 맞는 요소를 컨트롤 할 수 있다.

     

    만약 복수로 <p> 태그의 한번에 컨트롤 하고 싶다면 다음과 같이 하면 된다.

     

    <body>
        <p> 일반 문장입니다 1. </p>
        <p> 일반 문장입니다 2. </p>
        <p> 일반 문장입니다 3. </p>
    
        <script>
    
            for(i=0; i < document.getElementsByTagName('p').length; i++){
                document.getElementsByTagName('p')[i].innerHTML = "유사배열 "+(i+1);
            }
            
            // for 문을 이용하면 인덱스의 값을 자동으로 바꾸면서
            // 해당 HTML에서 원하는 모든 요소를 한번에 컨트롤 할 수 있다.
            // 참고로 해당 코드를 실행하면 다음과 같다.
            // 각각의 <p> 태그 내용은
            // "유사배열 1", "유사배열 2", "유사배열 3"로 바뀐다.
    
        </script>
    </body>

     

    for문을 이용해서 인덱스를 자동으로 지정하면 HTML 문서 내에서 해당 조건에 맞는 모든 요소를 컨트롤할 수 있다.

     

    하지만 뭔가 복잡하다. 더 쉬운 방법도 존재한다.

     

    하지만 지금은 아니고 추후 유사배열로 다시 정리할 예정이다.

     

    우선 여기선 남은 두 메서드를 살펴보자.

     

    2. getElementsByClassName()

     

    대략 풀어쓰면 이렇다.

     

    '파라미터로 주어진 문장과 일치하는 클래스 네임을 가진 복수 요소들의 객체를 반환한다.'

     

    즉 'getElementsByClassName'는 원하는 조건에 맞는 클래스 속성을 가진 요소의 객체를 컨트롤 할수 있게 한다.

     

    그리고 당연하게도 복수 요소에 접근하는 메서드라

     

    'getElementsByTagName'과 같이 유사배열의 형태로 객체를 반환한다.

     

    <body>
        <p class = "t_class"> 클래스적용 문장입니다 1. </p>
        <p class = "t_class"> 클래스적용 문장입니다 2. </p>
        <p class = "t_class"> 클래스적용 문장입니다 3. </p>
    
        <script>
            
            document.getElementsByClassName('t_class')[0].innerHTML = "클래스로 접근합니다 1";
            document.getElementsByClassName('t_class')[1].innerHTML = "클래스로 접근합니다 2";
            document.getElementsByClassName('t_class')[2].innerHTML = "클래스로 접근합니다 3";
            // 해당 내용을 실행하면 다음과 같다
            // <p> 태그의 내용은 순서대로 이렇게 바뀐다.
            // "클래스로 접근합니다 1"
            // "클래스로 접근합니다 2"
            // "클래스로 접근합니다 3"
            
        </script>
    </body>

     

    사용법도 'getElementsByTagName'과 같다.

     

    복수의 요소를 한번에 컨트롤 하는 것도 동일하다.

     

    <body>
        <p class = "t_class"> 클래스적용 문장입니다 1. </p>
        <p class = "t_class"> 클래스적용 문장입니다 2. </p>
        <p class = "t_class"> 클래스적용 문장입니다 3. </p>
    
        <script>
    
            for(i=0; i < document.getElementsByClassName('t_class').length; i++){
                document.getElementsByClassName('t_class')[i].innerHTML = "클래스로 접근합니다";
            }
            // 해당 코드 실행시
            // <p> 태그의 내용은 모두 "클래스로 접근합니다"로 변경
    
        </script>
    </body>

     

    이 또한 더 편하게 복수의 요소를 컨트롤할 수 있는 방법이 있지만 우선은 넘어간다.

     

    3. querySelectorAll()

     

    대략 해석하면 다음과 같다.

     

    '파라미터를 통해 주어진 선택자를 이용해 조건에 맞는 복수 요소들의 객체를 반환한다.'

     

    앞서 말한 메서드들은 'tagname', 'class', 'id' 와 같이 'HTML'에서 제공하는 기능을 가지고

     

    반환반을 요소들을 선택할 수 있었다.

     

    하지만 'querySelectorAll()'를 쓰면 CSS 선택자를 이용하여 요소들을 선택할 수 있다.

     

    이 방법을 이용하면 'id', 'class' 처럼 일일이 속성을 지정하지 않아도 요소들을 구분하여 선택이 가능하다.

     

    'tagname'의 경우 'HTML'에서 조건에 해당하는 모든 요소들의 객체를 반환하기에 부담스럽다.

     

    하지만 'querySelectorAll'는 조금 더 세밀한 조건 설정을 통해 원하는 객체 반환이 비교적 쉽다.

     

    우선 코드를 보자.

     

    <body>
        <ul>
            <li> 일번 </li>
            <li> 이번 </li>
        </ul>
        <div>
            <li> 일번 </li>
            <li> 이번 </li>
        </div>
    
        <script>
            
            document.querySelectorAll('li')[0].innerHTML = " ul > li 쿼리셀렉터로 접근합니다";
            document.querySelectorAll('li')[1].innerHTML = " ul > li 쿼리셀렉터로 접근합니다";
            document.querySelectorAll('li')[2].innerHTML = " div > li 쿼리셀렉터로 접근합니다";
            document.querySelectorAll('li')[3].innerHTML = " div > li 쿼리셀렉터로 접근합니다";
            
            // 모든 <li> 태그 내의 내용은 순서대로 아래처럼 바뀐다.
            // " ul > li 쿼리셀렉터로 접근합니다";
            // " ul > li 쿼리셀렉터로 접근합니다";
            // " div > li 쿼리셀렉터로 접근합니다";
            // " div > li 쿼리셀렉터로 접근합니다";
    
        </script>
    </body>

     

    위 코드는 우선 문서 내의 모든 <li> 태그의 객체를 반환받아 컨트롤하는 코드다.

     

    'tagname' 선택과 비슷한 모양새다.

     

    하지만 이럴 때보다 아래 코드의 경우 'querySelectorAll'의 진가가 드러난다.

     

    <body>
        <ul>
            <li> 일번 </li>
            <li> 이번 </li>
        </ul>
        <div>
            <li> 일번 </li>
            <li> 이번 </li>
        </div>
    
        <script>
            
            document.querySelectorAll('ul > li')[0].innerHTML = " ul > li 쿼리셀렉터로 접근합니다";
    
            document.querySelectorAll('div > li')[0].innerHTML = " div > li 쿼리셀렉터로 접근합니다";
    
            // 위 코드를 실행하면 <li> 태그는 순서대로 이렇게 바뀐다.
    
            // "ul > li 쿼리셀렉터로 접근합니다"
            // "이번"
            // "div > li 쿼리셀렉터로 접근합니다"
            // "이번"
    
        </script>
    </body>

     

    전의 코드처럼 투박하게 <li> 태그를 전부 선택한 것이 아니라 CSS 선택자 방식을 이용했다.

     

    각각 <div>, <ul>의 아래 있는 <li> 태그를 구분하여 선택했다.

     

    당연히 유사배열을 통해 돌려받는 인덱스도 달라진다.

     

    그리고 당연히 'querySelectorAll' 메서드도 조건에 맞는 모든 요소를 선택하고 싶다면 for 문을 쓴다.

     

Designed by Tistory.