Loading the catalog…
Loading the catalog…
JavaScript_Day.7 DOM 트리를 타고 이동하기, 이벤트 객체, 타이머, 그리고 구조 분해 할당까지. 어제까지가 "태그 하나를 골라서 바꾸기"였다면, 오늘은 "태그 사이의 관계를 따라 움직이기"였다. 학습 일곱 번째 날이다. 오늘 배운 내용은 이렇다. 입력값 계산 : value 와 eval DOM 탐색 : 부모·자식·형제 노드, 텍스트 노드와 요소 노드의 차이 이벤트 객체 : type , target , currentTarget , preventDefault() 폼 요소 다루기 : name 접근, keyup , checked , disabled , label display 속성 : block, inline, inline-block data- 사용자 정의 속성 타이머 : setInterval , setTimeout , 외부 JS 파일, window.open , location classList 구조 분해 할당 1. 입력값으로 계산하기 클릭하면 정답이 나타나는 계산 문제 <h1>계산해봅시다</h1> <hr> <!-- 구분선 --> <div><span class="ans">3+4=</span><span class="btn">답</span></div> <div><span class="ans">5*20+60=</span><span class="btn">답</span></div> <div><span class="ans">20/5-4*5=</span><span class="btn">답</span></div> <script> // 같은 이름의 CSS 선택자가 여러 개 있으면 목록(배열처럼)으로 선택된다 let ans = document.querySelectorAll('.ans'); let btn = document.querySelectorAll('.btn'); btn.forEach(function (btn, i) { btn.addEventListener('click', function () { let ans2 = ans[i].textContent.replace('=', ''); // '3+4=' → '3+4' btn.textContent = eval(ans2); // 계산 결과로 교체 }); }); </script> 식 클릭 후 3+4= 7 5*20+60= 160 20/5-4*5= -16 querySelectorAll 로 가져온 목록을 forEach 로 돌면서, 각 버튼에 클릭 이벤트를 붙였다. forEach 의 두 번째 인자 i (인덱스)로 같은 순서의 식( ans[i] )을 찾는 것이 핵심이다. replace('=', '') 로 = 를 지워야 eval 이 식으로 계산할 수 있다. 추가로 정리: forEach는 NodeList에는 되고, HTMLCollection에는 안 된다 가져오는 방법 결과 타입 forEach querySelectorAll NodeList 사용 가능 getElementsByTagName , getElementsByClassName , children HTMLCollection 사용 불가 Day.5에서 getElementsByTagName 결과를 for in 으로 돌 때 오류가 났던 것도 이 HTMLCollection 때문이다. HTMLCollection은 일반 for 문으로 돌면 안전하다. 식을 입력해서 계산하기 식<input type="text" id="susik"><br> 값<input type="text" id="result"><br> <input type="button" value="계산" onclick="calcu()"> <script> function calcu() { let susik = document.querySelector('#susik'); let result = document.querySelector('#result'); result.value = eval(susik.value); console.log(typeof(result.value)); // string console.log(typeof(susik.value)); // string } </script> input 요소의 값은 .value 로 읽고 쓴다. value 는 사용자가 직접 입력한 값이며, 숫자를 입력해도 문자열 이다. input으로 계산 기능을 만들 때는 value 를 쓴다. 필기에는 result.value = eval(...) 뒤의 typeof 가 문자열이라고 되어 있다. 숫자 결과를 value 에 넣으면 문자열로 바뀌기 때문이다. 2. DOM 탐색: 노드 사이를 이동하기 부모 노드: parentNode <div class="frame"> <h1 class="head">제목</h1> <hr> <p class="p">본문 문단이다.</p> <button id="bu1">클릭</button> </div> <script> let bu1 = document.querySelector('#bu1'); bu1.addEventListener('click', function () { this.parentNode.style.backgroundColor = 'yellow'; // 버튼의 부모(div) this.parentNode.style.border = '3px solid blue'; }); </script> this 는 클릭된 버튼이고, this.parentNode 는 그 부모 노드 ( div.frame )다. border 는 두께 모양 색 순서라서 3px solid blue 는 "3px짜리 실선, 파란색 테두리"다. 탐색 속성 정리 속성 설명 parentNode 부모 노드 childNodes 모든 자식 노드 (텍스트, 주석 포함) children 자식 요소 노드만 firstChild / lastChild 첫 / 마지막 자식 노드 (텍스트, 주석 포함) firstElementChild / lastElementChild 첫 / 마지막 자식 요소 (공백 무시) nextElementSibling 다음 형제 요소 (공백 무시) previousElementSibling 이전 형제 요소 (공백 무시) 바로잡기 : 필기에는 firstChild 를 "첫번째 자손 노드", 이전 형제를 prevElementSibling 이라고 적었다. firstChild 는 바로 아래 단계인 자식 노드이고(자손은 손자까지 포함하는 말이다), 이전 형제 속성의 정확한 이름은 previousElementSibling 이다. 텍스트 노드와 요소 노드 <div class="frame"> <h1 class="head">제목</h1> <p class="p">본문 문단이다.</p> <button id="bu1">클릭</button> </div> <script> let f = document.querySelector('.frame'); console.log(f.childNodes.length); // 7 f.childNodes[1].style.color = 'red'; // <h1>이 빨간색으로 console.log(f.children.length); // 3 </script> childNodes 가 7인 이유는 태그 사이의 줄바꿈과 공백도 텍스트 노드 로 세기 때문이다. 인덱스 노드 0 텍스트 노드: <div> 여는 태그 뒤의 줄바꿈+공백 1 요소 노드: <h1> 2 텍스트 노드: </h1> 와 <p> 사이의 줄바꿈+공백 3 요소 노드: <p> 4 텍스트 노드: </p> 와 <button> 사이의 줄바꿈+공백 5 요소 노드: <button> 6 텍스트 노드: </button> 뒤의 줄바꿈+공백 children 은 요소 노드만 세므로 h1 , p , button 으로 3 이다. 그래서 childNodes[1] 처럼 인덱스를 쓸 때는 공백 때문에 번호가 어긋나기 쉽고, 요소만 쓰고 싶다면 children 이나 ~Element~ 속성을 쓰는 것이 편하다. firstChild와 firstElementChild <div id="frame"> <p>one</p> <p>two</p> </div> <script> let f1 = document.getElementById('frame'); let first = f1.firstElementChild; document.write(f1.firstChild + '<br>'); // [object Text] (공백 텍스트 노드) document.write(first); // [object HTMLParagraphElement] (<p>one</p>) </script> firstChild : 모든 노드 중 첫 번째. 텍스트와 주석도 포함한다. firstElementChild : 요소 노드 중 첫 번째. 텍스트와 공백은 무시한다. 형제 노드와 텍스트 노드 바꾸기 <div class="frame"> <!-- 처음으로 추가된 텍스트 --> <h1>javascript</h1> <div class="c"> <h2>css</h2> <p>h2 다음에 오는 문단이다.</p> </div> <!-- 마지막에 추가된 텍스트 --> </div> <script> let f1 = document.querySelector('.frame'); f1.firstChild.textContent = '처음으로 추가된 텍스트'; f1.lastChild.textContent = '마지막에 추가된 텍스트'; let c1 = document.querySelector('.c'); let h2 = document.querySelector('.c h2'); console.log(h2.textContent); // css // h2의 다음 형제 요소 = p h2.nextElementSibling.style.border = '2px solid red'; // div.c의 이전 형제 요소 = h1 c1.previousElementSibling.style.border = '2px dotted blue'; </script> 여기서 firstChild 와 lastChild 는 주석이 아니라, 주석 앞뒤의 공백 텍스트 노드 다. 그 노드의 textContent 를 바꾼 것이라 화면에 글이 나타난다. h2.nextElementSibling 은 h2 와 같은 부모 아래에서 바로 다음에 있는 요소( p )다. 3. 이벤트 객체 <p id="mouse1">마우스</p> <!-- html 인라인 이벤트에서는 매개변수 이름을 event로 쓴다 --> <button onclick="on(event)">클릭!</button> <script> function on(event) { // event: 현재 발생한 이벤트 객체 let event1 = event.type + '<br>' // 이벤트 종류 + event.target + '<br>' // 이벤트가 발생한 요소 + event.currentTarget + '<br>' // 이벤트가 연결된 요소 + event.defaultPrevented; // 기본 동작이 취소되었는가 document.querySelector('#mouse1').innerHTML = event1; } </script> 속성 설명 이 예제의 값 event.type 이벤트 종류 click event.target 이벤트가 발생한 요소 버튼 event.currentTarget 이벤트 핸들러가 연결된 요소 버튼 event.defaultPrevented 기본 동작이 취소되었는지 (취소됨: true) false 이 예제에서는 버튼에 직접 연결했기 때문에 target 과 currentTarget 이 같다. 자식 요소를 클릭했는데 핸들러가 부모에 달려 있는 경우에는 둘이 달라질 수 있다. preventDefault: 기본 동작 막기 태그에는 기본 동작 이 있다. 링크는 클릭하면 페이지가 이동하고, 체크박스는 클릭하면 체크된다. 이 기본 동작을 코드로 막을 수 있다. <!-- 링크의 기본 동작은 페이지 이동이다 --> <!-- onclick이 true를 반환하면 이동, false를 반환하면 이동 취소 --> <a href="https://example.com" onclick="return on()">이동할 거냐</a><br> <!-- 체크박스의 기본 동작은 체크되는 것이다 --> <input type="checkbox">커피<br> <input type="checkbox" onclick="no(event)">빵 <script> function on() { let n = confirm('정말 이동할건가요?'); // 확인: true, 취소: false return n; } function no(e) { e.preventDefault(); // 이벤트의 기본 동작을 강제로 취소 } </script> e.preventDefault() : 기본 동작을 취소시키는 메소드 다. e.defaultPrevented : 기본 동작이 취소되었는지 확인 하는 값이다. 함수가 아니라 속성이므로 () 를 붙이지 않는다. 이름이 비슷해서 헷갈리는데, "막아라"는 preventDefault() , "막혔나?"는 defaultPrevented 로 구분하기로 했다. 위 예제에서 "빵" 체크박스는 클릭해도 체크되지 않고, "커피"는 정상적으로 체크된다. 4. 폼 요소 다루기 폼 요소에 접근하는 3가지 방법 <form name="test"> <input type="text" name="test2" placeholder="입력해주세요"> </form> <script> // 1. document.폼이름.요소이름 let n = document.test.test2; n.style.border = '2px solid red'; // 2. document.forms['폼이름'].elements['요소이름'] let n2 = document.forms['test'].elements['test2']; n2.style.backgroundColor = 'yellow'; // 3. document.forms['폼이름']['요소이름'] let n3 = document.forms['test']['test2']; n3.style.fontSize = '50px'; </script> 세 방법 모두 같은 input 을 가리킨다. 형태가 짧은 순서대로 1번, 3번, 2번이다. keyup: 입력할 때마다 실시간으로 반영하기 <form name="test"> <input type="text" id="aa" name="test2" placeholder="입력해주세요"> </form> <div id="div1"></div> <script> let input = document.forms['test']['test2']; let n2 = document.querySelector('#div1'); // 키보드를 입력했을 때의 이벤트 (고전 이벤트 방식) input.onkeyup = function () { let n3 = this.value; // input에 입력한 값 n2.textContent = n3; // div 영역에 띄운다 }; </script> 키를 눌렀다 뗄 때마다 input 의 값이 div 에 그대로 나타난다. 필기에서는 innerHTML 로 넣었는데, 사용자 입력을 그대로 넣는 곳이라서 Day.6에서 정리한 이유로 textContent 로 바꿨다. disabled, label, checked 주민번호 뒷자리 첫 숫자를 입력하면 성별 라디오 버튼이 자동으로 선택되는 실습이다. <form name="test" class="a1"> <input type="text" name="input_1" value="001111" disabled> <!-- disabled: 입력하지 못하도록 막는다 --> <input type="text" name="input_2" placeholder="주민번호 뒷자리 입력하기"> <input type="radio" name="ch" id="male"> <label for="male">남</label> <!-- label로 구분 --> <input type="radio" name="ch" id="female"> <label for="female">여</label> </form> <script> let n = document.test.input_2; let male = document.querySelector('#male'); let female = document.querySelector('#female'); n.onkeyup = function () { let num = this.value; if (num >= 1 && num <= 4) { if (num == 1 || num == 3) { female.checked = false; male.checked = true; // 체크한다 } else { male.checked = false; female.checked = true; } } }; </script> disabled : 입력을 막는 속성이다. <label for="id"> : for 에 input 의 id 를 넣으면 글자를 눌러도 해당 입력이 선택된다. radio 나 checkbox 타입에는 checked 라는 상태 필드가 있어서, true / false 로 체크 상태를 바꾼다. 추가로 정리: 라디오 버튼은 한쪽만 true로 해도 된다 name 이 같은 라디오 버튼은 하나만 선택되므로, male.checked = true 만 해도 female 은 자동으로 해제된다. 위 코드의 female.checked = false 는 없어도 결과가 같다. 5. display 속성: 블록, 인라인, 인라인 블록 구분 블록 박스 인라인 박스 인라인 블록 박스 속성 display: block display: inline display: inline-block 예시 태그 div , p , h1~h6 label , a , span , strong (속성으로 지정) 새 라인에서 시작 항상 새 라인 못 함 (라인 안에 있음) 못 함 (인라인 특성) 옆에 다른 요소 배치 불가능 가능 가능 (인라인 특성) width, height 조절 가능 불가능 가능 (블록 특성) padding, margin 조절 가능 위아래 margin은 적용 안 됨 가능 (블록 특성) 필기에는 인라인 박스의 예로 textarea 와 input 도 적었는데, 이 둘은 인라인처럼 줄 안에 놓이지만 width와 height를 조절할 수 있다. 그래서 기본값이 사실상 인라인 블록에 가깝다. 위 표의 인라인 예시는 label , a , span , strong 만 남겼다. <style> div { border: 1px solid salmon; color: blue; background-color: yellow; } </style> css <div style="display: none;">재밌음</div> <br> css <div style="display: inline; height: 50px;">재밌음</div> css <div style="display: inline-block; height: 50px;">재밌음</div> css <div style="display: block;">재밌음</div> 같은 div 에 속성만 바꿔서 확인했다. none : 화면에서 사라지고 자리도 차지하지 않는다. inline : 글자 크기만큼만 차지한다. height: 50px 을 줘도 적용되지 않는다. inline-block : 옆에 붙으면서 height: 50px 이 적용된다. block : 새 줄에서 시작해 한 줄을 다 차지한다. 6. 폼 제출 이벤트로 목록 만들기 <h3>정보입력</h3> <form id="info"> <p>이름 <input type="text" id="name"></p> <p>주소 <input type="text" id="addr"></p> <input type="submit" value="정보입력"> </form> <p id="output"></p> <!-- 완성되면 이런 모양: <p>홍길동 , 서울</p> --> <script> let form = document.getElementById('info'); let nameInput = document.getElementById('name'); let addr = document.getElementById('addr'); let output = document.getElementById('output'); // submit 버튼을 눌렀을 때 발생하는 이벤트 → onsubmit form.onsubmit = function (e) { e.preventDefault(); // 기본 제출 동작(새
What RADAR observed and classified to build this opportunity. It is what the source published, not a verification that the offer is still active.
JavaScript_Day.7. JavaScript_Day.7 DOM 트리를 타고 이동하기, 이벤트 객체, 타이머, 그리고 구조 분해 할당까지. 어제까지가 "태그 하나를 골라서 바꾸기"였다면, 오늘은 "태그 사이의 관계를 따라 움직이기"였다. 학습 일곱 번째 날이다. 오늘 배운 내용은 이렇다. 입력값 계산 : value 와 eval DOM 탐색 : 부모·자식·형제 노드, 텍스트 노드와 요소 노드의 차이 이벤트 객체 : type , target , currentTarget , preventDefault() 폼 요소 다루기 : name 접근, keyup , checked , disabled , label display 속성 : block, inline, inline-block data- 사용자 정의 속성…
Open source