JavaScript DOM 조작 —
getElementById · style 동적 변경 완전 정리
버튼을 누르면 문장의 색·크기·테두리가 실시간으로 바뀌는 코드다. HTML은 그대로인데 화면이 변하는 이유는, JavaScript가 document.getElementById()로 실제 태그를 "객체"로 붙잡아서 그 객체의 style 프로퍼티를 직접 고쳐 쓰기 때문이다.
버튼을 누르기 전 (HTML에 적은 인라인 style="color:red" 그대로)
이것은 문장입니다.
「스타일변경」 버튼을 누른 후 (JS가 style을 덮어씀)
이것은
문장입니다.document.getElementById("mySpan")은 화면에 그려진 <span id="mySpan"> 태그를 찾아서, 그 태그를 통째로 조작할 수 있는 DOM 객체로 돌려준다. 텍스트나 좌표 몇 개가 아니라, 색·크기·자식 개수·이벤트까지 전부 프로퍼티로 붙어 있는 하나의 살아있는 대상이다. 그래서 span.style.color = "green"처럼 점(.)을 찍어서 그 안의 세부 항목에 접근할 수 있다.
getElementById는 먼저 나오는 것 하나만 돌려주고, 나머지는 무시된다.만약 그런 id가 문서에 없으면 어떻게 될까? 에러가 나지 않고 조용히 null을 돌려준다. 이 null을 모르고 바로 .style을 찍으면 그때 비로소 에러가 터진다 (자주 하는 실수 참고).
span.style은 그 자체로 또 하나의 객체다. 그 안에 color, fontSize, border 같은 CSS 속성들이 프로퍼티로 미리 준비되어 있어서, span.style.color = "green"처럼 값만 대입하면 즉시 화면에 반영된다. 별도의 함수 호출 없이 대입(=) 한 줄로 스타일이 바뀌는 이유가 이것이다.
중요한 건 span.style이 딱 그 태그의 인라인 style 속성만 다룬다는 점이다. 외부 CSS 파일이나 <style> 태그로 준 스타일은 여기 들어있지 않다 — 이건 3번, 6번에서 실수로 자주 마주친다.
CSS에서는 font-size처럼 하이픈(-)으로 단어를 잇는다. 그런데 JavaScript에서 하이픈(-)은 "빼기 연산자"로 이미 예약되어 있다. span.style.font-size라고 쓰면 JS는 이걸 font라는 프로퍼티에서 size를 빼는 계산으로 오해해 문법 오류를 낸다. 그래서 하이픈을 없애고 다음 단어의 첫 글자를 대문자로 올리는 camelCase 규칙으로 이름을 바꿔서 쓴다.
background-color: red;
border-radius: 4px;
style.backgroundColor = "red";
style.borderRadius = "4px";
border나 color, margin처럼 원래 한 단어인 속성은 그대로 쓴다.
span.style.color = "green"을 실행하면, 브라우저는 이걸 실제 HTML 태그에 style="color: green"이라는 속성을 써넣은 것과 똑같이 취급한다. 즉 JS가 CSS를 인라인 스타일로 직접 태그에 새겨 넣는 셈이다.
이게 왜 중요하냐면, CSS의 우선순위(specificity) 규칙에서 인라인 스타일은 외부 스타일시트나 <style> 태그보다 항상 강하다. 그래서 원래 span { color: red; }라고 CSS로 정해뒀어도, JS가 span.style.color = "green"을 실행하는 순간 무조건 초록색으로 덮어써진다.
스타일을 "바꾸는" 것 말고, 태그가 이미 갖고 있는 정보를 그냥 "읽기"만 할 수도 있다. 아래는 <p> 태그 하나를 잡아서 그 안의 여러 프로퍼티를 순서대로 읽어 문자열에 이어 붙이는 코드다.
여기서 눈여겨볼 값 셋이 있다. tagName은 항상 대문자로 나온다("P"이지 "p"가 아니다). innerHTML은 태그 안쪽의 텍스트뿐 아니라 <span> 태그까지 포함한 HTML 원문 자체를 문자열로 준다. childElementCount는 자식 "요소(태그)"만 세므로, 순수 텍스트 노드는 세지 않고 여기서는 span 1개만 잡혀 1이 나온다.
- CSS로
width: 200px라고 "써준" 값이 아니라, 테두리·패딩까지 포함해 브라우저가 실제로 화면에 그린 픽셀 크기다 - 그래서 폰트, 줄바꿈, 부모 크기에 따라 매번 값이 달라질 수 있다
- margin은 포함하지 않는다 (테두리 바깥은 셈에서 제외)
두 원본 코드는 클릭 이벤트를 다루는 방식이 서로 다르다. 첫 번째 코드는 onclick="change()"처럼 이름 있는 함수를 호출하고, 그 함수 안에서 다시 getElementById로 대상을 찾는다. 두 번째 코드는 onclick="this.style.color='teal'"처럼 this 하나로 바로 자기 자신을 가리킨다.
함수 안에서 getElementById로 대상을 다시 찾아야 함
여러 버튼이 같은 함수를 재사용하기 좋음
this = 이벤트가 걸린 그 태그 자신
대상을 다시 찾을 필요가 없어 짧고 빠름
this는 항상 그 이벤트가 걸려 있는 태그를 가리킨다. <p onclick="this.style.color='teal'">라면 this는 바로 그 <p> 자신이다.즉 this.style.color = 'teal'은 "document.getElementById(자기자신의id).style.color = 'teal'"을 줄여 쓴 것과 결과가 같다. id를 몰라도, 심지어 id가 없어도 동작한다는 게 this의 장점이다.
| 실수 | 증상 | 해결 |
|---|---|---|
style.font-size처럼 하이픈 그대로 사용 |
SyntaxError 또는 값이 조용히 무시됨 | camelCase인 style.fontSize로 작성 |
getElementById에 넣은 id가 오타·존재하지 않음 |
null이 반환되고 이후 .style 접근 시 "Cannot read properties of null" |
id 철자 재확인, 콘솔에서 변수 먼저 console.log로 확인 |
p.style.color로 CSS 파일에 정의된 색을 읽으려 함 |
인라인 style이 없으면 빈 문자열("")만 반환되어 원하는 값이 안 나옴 | 렌더링된 실제 값이 필요하면 getComputedStyle(p).color 사용 |
style.width = 6처럼 단위 없는 숫자만 대입 |
스타일이 적용되지 않고 무시됨 | 반드시 "6em", "200px"처럼 문자열+단위로 대입 |
화살표 함수 안에서 this가 이벤트 대상을 가리킨다고 착각 |
this가 예상과 다른 대상(예: window)을 가리켜 오류 발생 | 인라인 핸들러·일반 function에서는 this=대상 요소, 화살표 함수는 피하기 |
| 같은 id를 두 개 이상의 태그에 부여 | getElementById가 항상 먼저 나온 태그만 반환 |
문서 내 id는 유일하게, 반복 요소는 class 사용 |
핵심 한 줄 요약
Tags
'php' 카테고리의 다른 글
| jQuery 노드 함수 — length, text, remove, console.log 완전 정리 (0) | 2026.06.24 |
|---|---|
| jQuery 기초 — ready, click, css, text 완전 정리 (0) | 2026.06.24 |
| jQuery Mobile 중첩 접이식 패널 — nested collapsible 완전 정리 (0) | 2026.06.24 |
| jQuery Mobile 접이식 패널 — collapsible 완전 정리 (0) | 2026.06.24 |
| jQuery Mobile 다이얼로그 select — multiple, data-native-menu 완전 정리 (0) | 2026.06.24 |
왕진 블로그

댓글