JavaScript innerHTML · this —
내용 교체와 이벤트 대상 완전 정리
오늘은 실무에서 정말 자주 마주치는 두 가지 짝꿍 개념을 함께 본다. 하나는 innerHTML — 요소의 내용을 문자열째로 바꿔치기하는 방법이고, 다른 하나는 this — 이벤트가 걸린 요소 자기 자신을 함수에 전달하는 방법이다. 두 코드 모두 클릭 한 번으로 화면이 바뀌는 예제다.
여기에 클릭하세요
innerHTML은 요소의 여는 태그와 닫는 태그 사이에 있는 모든 것을 하나의 문자열로 취급한다. p.innerHTML = "새 내용"처럼 대입하는 순간, 그 안에 있던 글자든 <span>이든 자식 요소가 몇 개였든 전부 지워지고 새 문자열로 완전히 갈아끼워진다. "이 부분만 바꿔줘"가 아니라 "안쪽 전체를 이걸로 교체해줘"라는 명령이다.
<p id="firstP"> 안에는 원래 "여기에 <span>클릭하세요</span>"가 들어있었다. change()가 실행되면 이 내용은 흔적도 없이 사라지고 "나의 강아지" 문장으로 완전히 바뀐다.핵심은 innerHTML이 대입된 문자열을 HTML 소스 코드로 다시 해석(파싱)한다는 점이다. "나의 <img src='media/puppy.png'> 강아지"라는 텍스트를 넣으면, 브라우저는 그 문자열 안의 <img>를 단순 글자가 아니라 진짜 이미지 태그로 다시 그려낸다. 그래서 결과 화면에는 "나의 [그림] 강아지"처럼 실제 이미지가 나타난다.
태그가 실제 요소로 렌더링됨.
이미지·서식 있는 내용 삽입에 사용.
태그를 써도 글자 그대로 출력됨.
사용자 입력 등 안전한 텍스트 삽입에 사용.
this는 코드에 미리 정해져 있는 값이 아니라, "함수가 지금 어떻게 호출됐는가"에 따라 그때그때 결정되는 특별한 키워드다. onclick="change(this, ...)"처럼 요소의 이벤트 속성 안에서 쓰인 this는, 그 이벤트가 걸려 있는 HTML 요소 자기 자신을 가리킨다. 버튼 A를 누르면 this = 버튼 A, 버튼 B를 누르면 this = 버튼 B다.
change(obj, size, color) 함수 입장에서는, 자신을 호출한 것이 버튼 A인지 버튼 B인지 div인지 스스로는 전혀 알 방법이 없다. 그래서 호출하는 쪽(HTML)에서 this를 첫 번째 인자로 직접 건네줘야, 함수 안에서 obj라는 매개변수로 그 요소를 넘겨받아 obj.style...처럼 조작할 수 있다.
onclick="change()"처럼 인자 없이 호출하면 함수 안의 obj는 undefined가 되고, obj.style.color = ...에서 "Cannot set properties of undefined" 에러가 난다.모든 DOM 요소는 style이라는 프로퍼티(하나의 객체)를 갖고 있다. 그 객체의 color, fontSize 같은 속성에 값을 대입하면, 그 요소의 인라인 style이 즉시 그 값으로 바뀐다. 이때 CSS 속성 이름의 하이픈(-)은 JS에서는 카멜케이스로 써야 한다는 점이 중요하다.
예제 2에는 버튼 2개와 div 1개, 총 3개의 클릭 대상이 있지만 함수는 change 하나뿐이다. this 덕분에 "누구를 바꿀지"는 호출할 때마다 달라지고, "어떻게 바꿀지"만 함수 안에 공통 로직으로 남겨둘 수 있기 때문이다. 만약 this를 쓰지 않았다면 버튼마다 changeA(), changeB(), changeDiv()처럼 요소 개수만큼 거의 똑같은 함수를 따로 만들어야 했을 것이다.
- 버튼이 10개, 100개로 늘어도 함수는 여전히 1개
- 공통 로직을 한 곳에서만 수정하면 모든 요소에 반영됨
- "이 요소를 어떻게 바꿀지"와 "누구인지"를 분리해서 생각할 수 있음
innerHTML은 문자열을 실제 HTML로 파싱해서 요소로 만들어주는 편리한 기능이지만, 반대로 말하면 그 문자열 안에 악성 <script>나 이벤트 속성이 섞여 있어도 그대로 실행될 수 있다는 뜻이다. 댓글, 검색어, 닉네임처럼 사용자가 직접 입력한 값을 검증 없이 innerHTML에 그대로 넣는 것은 Cross-Site Scripting(XSS) 공격의 대표적인 원인이다.
textContent를 쓰거나 서버·라이브러리 차원의 이스케이프 처리를 거쳐야 안전하다.| 실수 | 증상 | 해결 |
|---|---|---|
| innerHTML과 textContent 혼동 | 태그 문자열을 넣었는데 그림 대신 <img ...> 글자가 그대로 보임 |
태그를 실제 요소로 렌더링하려면 innerHTML, 순수 글자만 넣으려면 textContent |
onclick="change()"처럼 this를 안 넘김 |
함수 안 obj가 undefined가 되어 obj.style에서 에러 |
onclick="change(this, ...)"로 반드시 자기 자신을 전달 |
innerHTML += "..."를 반복 사용 |
매번 전체를 다시 파싱해 느려지고, 기존에 걸어둔 이벤트가 사라짐 | 가능하면 내용을 한 번에 조립해서 대입하거나 appendChild 사용 |
| onclick 속성 안 따옴표 중첩 실수 | "change(this, "30px", "red")"처럼 따옴표가 겹쳐 구문 오류 발생 |
바깥은 큰따옴표("), 안쪽 문자열은 작은따옴표(')로 통일 |
| 사용자 입력을 검증 없이 innerHTML에 대입 | 악성 스크립트가 실행되는 XSS 취약점 발생 가능 | 신뢰 못하는 값은 textContent 사용하거나 이스케이프 처리 후 삽입 |
핵심 한 줄 요약
Tags
'php' 카테고리의 다른 글
| JavaScript 알까기 게임 - 랜덤 배치와 타이머 완전 정리 (0) | 2026.07.15 |
|---|---|
| JavaScript document.write() — 문서에 직접 출력 완전 정리 (0) | 2026.07.15 |
| JavaScript document 객체 — location·URL·readyState 완전 정리 (0) | 2026.07.15 |
| MySQL SUM 컬럼곱 — 가격×수량 합산 집계 완전 정리 (0) | 2026.07.15 |
| MySQL LIMIT 복사 · ADD CONSTRAINT — 제한 복사·PK 추가 완전 정리 (0) | 2026.07.15 |
왕진 블로그

댓글