Front_End [JS기반]/자바스크립트

[ 3D Web : Front _ JavaScript ] innerHTML, innerText, textContent 차이 + insertAdjacentHTML

안다미로 : APP & Web3 & D.S 2024. 10. 29. 23:17

 

 

 

 

[ 3D Web : Front _ JavaScript ]

 innerHTML, innerText, textContent 차이 + insertAdjacentHTML

 

 

 


 

 

∇ JS : 텍스트를 읽어오는 속성 : innerHTML, innerText, textContent 비교해보기


목  차


1. innerHTML
    1-1. innerHTML이란
    1-2. innerHTML의 단점
    1-3. innerHTML의 성능과 대용
    
2. innerAdjacentHTML

3. innerText
    3-1. innetTExt란
    3-2. innerHTML과 innerText 비교
    
4. textContent

 

 


 

 

1. [ innerHTML ]


 

    1 - 1 . innerHTML이란.

 

   ' innerHTML'은  "Element"의 속성으로, element내에 포함된 HTML 또는 XML 마크업을 불러오거나,

      태그와 함께 입력하여 내용을 직접 설정할 수 있습니다.

 

   

    즉,  innerHTML을 사용하면

             내부 HTML코드를 JavaScript 코드에서 새 내용으로 손쉽게 변경할 수 있습니다.

 

// html 코드와 함께 작성 가능
document.documentElement.innerHTML = "<p>innerHTML test입니다.</p>"
// 스타일 적용
document.documentElement.innerHTML = 
  "<span style='color:blue'>innerHTML style test입니다.</span>"
 
// 이런 식으로 빈 문자열을 넣으면 body의 전체 내용을 지울 수 있다.
document.body.innerHTML = "";

 

 

      innerHTML은 유용한 메서드이고, 자주 사용하지만 치명적인 단점을 가지고 있습니다.

 

 

 

    1 - 2 . innerHTML의 단점.

               

                 MDN에 따르면, innerHTML은 XSS( Cross-Site-Scripting ) 공격에 취약하다는 약점을 가지고 있습니다.

 

 

 

              ※ XSS란?

                     - XSS ( Cross-Site-Scripting )은 악의적인 목적을 가진 이(해커)가

                           웹사이트에 악성 스크립트를 주입하는 행위를 의미합니다. 

 

                           - 사용자의 입력을 받기 위해 만들어진 ' input', 'textarea' 와 같은 창에서

                               누군가가 악의적인 스크립트를 작성하고,  그 스크립트가 innerHTML과 연결되어 파싱을 거친 뒤 

                               코드단에 주입되면, 관리자(페이지 소유자)가 예상하지 못한 결과가 발생할 수 있습니다.

 

                          - 스크립트의 내용에 따라서 '쿠키'나 '세션 토근값'등의 탈취도 가능해져서, 

                            이를 인증방식이나 세션관리에 활용하고 있는 사이트에 침입하거나 중대한 피해를 입힐 수 있습니다.

 

 

 

    1 - 3 . innerHTML의 성능과 대용.

 

               - 이러한 이유로 인해서 innerHTML의 사용은 지양하는 것이 좋으며, 

                     일반 텍스트를 삽입 할 때는 Node.textContent를 사용하는 것이 권장됩니다.

                         (이건 밑에서 확인)

 

               - 세부적인 기능과 동작 방식은 다르지만 innerHTML 대신 사용할 수 있는 문법들은

                      " innerText " ,  " textContent ",  " insertAdjacentHTML " 가 있습니다.

 

 

                - innerHTML의 동작 방식은 element가 기존에 가지고 있던 자식 요소를 파싱 하고서

                     새 값으로 들어온 new DOMString 또한 파싱하여서  DocumentFragment 객체를 생성합니다.

                        

                   이렇게 파싱 된 객체를 element의 innerHTML에 넣어줌으로써 element의 DOM 요소가

                        새로운 모습으로 변하게 되는 과정을 거칩니다.

 

                   따라서 파싱을 거치는 innerHTML은 강력한 만큼 성능상의 약점을 지니는데,

                      대체 방법을 사용하면 성능면에서 이점을 가져갈 수 있습니다.

 

         

                - 일반 텍스트의 삽입만을 원할 경우에는 innerText, textContent 두 문법을 사용할 수 있지만,

                   textContent는 원시 텍스트를 다루며 성능상의 이점이 더 높기 때문에

                   textContent 사용이 더 권장됩니다.

 

 

 

 

                - 만약에 HTML 요소를 직접적으로 삽입하고 싶다면,

                   insertAdjacentHTML을 innerHTML 대신 사용할 수 있는데 

                  '보안상의 이슈가 해결되진 않았지만(심각한데?)  insertAdjacentHTML은 자식 요소의 파싱 과정이

                  생략되기 때문에 성능상 훨씬 더 좋은 우위를 차지합니다.

 

 

                   


2. [ insertAdjacentHTML]


   -   insertAdjacentHTML() 메서드는 HTML & XML 같은 특정 텍스트를 파싱하고

       특정 위치에서 DOM tree 안에 원하는 node들을 추가합니다.

 

  -  이미 사용중인 element는 다시 파싱 하지 않습니다.

      그러므로, element 안에 존재하는 element를 건드리지 않습니다.

 

 -  innerHTML 보다 작업이 덜 드므로 속도가 빠릅니다.

 

- insertAdjacentHTML()를 사용하면 시작 태그의 앞, 시작 태그의 뒤, 종료 태그 앞, 종료 태그 뒤에

      노드를 삽입하는 것이 가능합니다.

element.insertAdjacentHTML(position, text);

 

 

           ※ position에는 아래 단어들만 사용 가능합니다.

 

                   ○ " beforebegin" : 타겟 요소의 전(형제 레벨)에 생성됩니다.   - > 시작 태그의 앞 ( 형제 레벨)

 

                   ○ " afterbegin" : 타겟 요소의 다음(자식 요소)에 생성됩니다.   - > 시작 태그의 뒤 ( 자식 요소)

 

                   ○ " afterend" : 타겟 요소의 끝나는 태그 바로 다음 (형제 레벨)에 요소를 생성.   - > 종료 태그 뒤 ( 형제 레벨)

 

 

              ex)

// <div id="one">one</div>
var d1 = document.getElementById('one');
d1.insertAdjacentHTML('afterend', '<div id="two">two</div>');
 
// At this point, the new structure is:
// <div id="one">one</div><div id="two">two</div>

  

 


3. [ innerText ]


 

    3 - 1 . innerHTML의 성능과 대용.

 

    innerText는 'Element'의 속성으로,

    element 내에서 사용자에게 보이는 text값들을 가져오거나 설정 가능합니다.

 

// innerHTML과 달리 text값만 다루기 때문에 html태그 사용 불가능
document.documentElement.innerText = "innerText test 입니다."
 
// html태그를 넣으면 태그도 text값으로 인식하고 
// <p>innerText test 입니다.</p> 문자열 그대로 적용함.
document.documentElement.innerText = "<p>innerText test 입니다.</p>"

 

 

    3 - 2 . innerHTML과 innerText 비교.

const innerT = document.getElementById('innerT');
innerT.innerText = "<div style='color:red'>innerText test입니다.</div>";
console.log(innerT)
// 스타일 적용되지 않은 기본 폰트로
<div style='color:red'>innerText test입니다.</div> 출력
 
const innerH = document.getElementById('innerH');
innerH.innerHTML = "<div style='color:red'>innerHTML test입니다.</div>";
console.log(innerH)
// 스타일 적용된 빨간색 폰트로 innerHTML test입니다. 출력

 

 


4. [ textContent]


     textContent는 'Node'의 속성으로,  사용자에게 보여지는 text값만 읽어오는 innerText와는 달리

       <script> 나 <style> 태그에 상관없이 해당 노드가 가지고 있는 텍스트 값들을 모두 읽어옵니다.

<div id='content'>
  test 
  <span style='display:none'>innerText에서는 확인 불가 :) </span>
</div>

 

<div id='content'>
  test 
  <span style='display:none'>innerText에서는 확인 불가 :)</span>
</div>
 
const content = document.getElementById('content');
 
console.log(content.innerHTML);
// html 전체를 다 가져온다.
 
// test
// <span style='display:none'>innerText에서는 확인 불가 :)</span>
 
-----------------------------------------------------
  
console.log(content.innerText);
// 사용자에게 보여지는 텍스트만 가져옴
// 숨겨진 텍스트는 사용자에게 보여지지 않기 때문에 test만 가져옴
 
// test
 
-----------------------------------------------------
  
console.log(content.textContent);
// 숨겨진 텍스트까지 포함해서 텍스트값을 모두 다 가져옴
 
// test
// innerText에서는 확인 불가 :)