Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- MVC요청플로우
- 이벤트핸들러this
- 문제선택근거
- SEQUENCE
- 설정세팅
- 사면초가
- index
- JDBC
- 이벤트핸들러등록
- 전전긍긍
- Transaction
- JPA
- Ajax
- 공통기술
- DDD
- 디스크i/o
- MVC
- 공통규약
- TDD
- 냄새라도
- OOP
- springsecurity
- AOP
- 로그백
- 단위테스트
- SpringLegacy
- 커뮤니티서버
- 클린아키텍처
- model
- string
Archives
- Today
- Total
개발이군고구마
[JS] 이벤트 핸들러 방식과 this(DOM의 attribute/property) 본문
728x90
1. 문제상황
ajax
.. 받아온 결과값data
html(data);
[현재코드]
바닥 페이지에 빈 요소 노드 (=태그) 를 만들어 놓고 (레이어 페이지 처럼 동작하게끔)
비동기 통신으로 가져온 data(=html) 의 값을 jqeury html 메서드로 데이터 값을 넣
[문제상황]
해당 레이어가 닫힌 후에 "다시 통신" 할때, 프로퍼티 방식 (스크립트 태그 내) 으로 선언한 함수가 동작하지 않음
[시도해본 방법]
- 새로 data를 가져올 때 DOM에 대한 파싱을 하지 않고 기존에 DOM을 가져오는 건 아닐까 하여, document.ready 에 있는 메서드를 밖으로 빼봄
- jsp는 react 처럼 가상 돔을 비교하지 않는다.
- 새로 데이터를 불러왔기 때문에 DOM을 처음부터 끝까지 다시 그리기 때문에 상관 없음
- js의 캐싱 문제인 줄 알고 ajax 선언시에 cache를 false로 선언함
[원인]
- 스크립트 태그 안에 있는 js는 브라우저 캐싱이 있어서 다시 호출한다고 해도 새로 갱신되지 않음
- jqeury html 메서드가 기존에 있던 태그들을 지우지 않기 때문에
- 매번 호출할 때마다 바닥 페이지에 빈 요소 노드에 태그들이 "쌓임"
- 프로퍼티 방식으로 선언된 이벤트는 매핑된 DOM 요소에 이벤트를 주기 때문에 이전 js는 그때 만들어진 이전 DOM 요소를 가르키고 있음
- 따라서 새로 불러온 html 요소 노드에 이벤트가 먹지 않고 있었던 것
이전에, querySelectorAll 메서드를 사용해
새롭게 생성한 팝업 DOM 에 접근했을 때 메서드가 안먹는 현상이 있었음 (원인은 querySelectorAll이 갱신이 안됨)
-> 팝업 DOM 에 직접 이벤트를 주는 방식 (=프로퍼티 방식) 으로 해결한 적이 있었음
* 해결 방법은 다르지만, 팝업 레이어가 쌓이고 있었던 원인은 동일함*
[아래의 개념에 대한 이해부족]
- jqeury의 html 메서드가 작동하는 방식 (=>기존 요소 노드의 값을 재갱신하는지에 대한 여부)
- html 메서드는 기존 내용을 삭제하고 새로운 html이 집어넣어짐
- 하지만 제대로 작동하지 않았던 것은, 브라우저에서 html을 캐싱한 것 같음
- append 의 경우엔 기존의 내용을 유지한채로 html 집어넣음
- 이벤트 핸들러 등록
- 이벤트 핸들러가 가르키는 this
2. DOM의 어트리뷰트와 프로퍼티의 상관관계
1) 어트리뷰트
- HTML 요소의 초기 상태를 지정. HTML 어트리뷰트 값은 HTML 요소의 초기 상태를 의미하며 변하지 않음.
- 언제나 문자열 (예, checked 어트리뷰트의 값은 문자열)
2) 프로퍼티
- 사용자가 입력한 최신상태는 HTML 어트리뷰트에 대응하는 요소 노드의 DOM 프로퍼티가 관리
- 사용자의 입력에 의한 상태 변화에 반응하여 언제나 최신 상태 유지
- 문자열이 아닐 수도 있음 (예, checked의 프로퍼티 값은 boolean)
3. 이벤트 핸들러 등록방식
1) 이벤트 핸들러 어트리뷰트 방식(*작동했던 이벤트 핸들러)
<button onclick="sayHi('Lee')"> Click me!</button>
<script>
function sayHi(name) {
console.log(`Hi!${name}`);
}
</script>
- 여기서 function sayHi 내부의 this는 전역 객체 window
- 일반 함수로 호출되는 방식이기 때문에, 전역객체를 가르킴
- 다만 인수로 전달한 this의 경우 해당 이벤트를 바인딩한 DOM 요소를 가리킴
2) 이벤트 핸들러 프로퍼티 방식 (*작동하지 않았던 이벤트 핸들러)
<button> Click me!</button>
<script>
const $button = document.querySelector('button');
$button.onclick = function() {
console.log("button click");
}
</script>
- 이벤트 핸들러 내부의 this는 이벤트를 바인딩한 DOM 요소를 가르킴 (=button)
3) addEventListener 방식
<button> Click me!</button>
<script>
const $button = document.querySelector('button');
$button.addEventListener('click', function() {
console.log("button click");
})
</script>
이벤트 핸들러 내부의 this는 이벤트를 바인딩한 DOM 요소를 가르킴 (=button)
'FRONT' 카테고리의 다른 글
| [JS] 브라우저 렌더링 과정 (캐싱/SSR) (0) | 2024.09.13 |
|---|---|
| [JS] aysnc와 await의 작동 순서 (Response.json()으로부터 촉발된) (0) | 2024.07.21 |
| [JS] 자바스크립트 동작 원리 2 (비동기와 이벤트루프) (0) | 2024.06.30 |
| [JS] 자바스크립트 동작 원리 1 (스레드, 동기, 비동기) (0) | 2024.06.22 |
| [React] 컴포넌트를 리랜더링 하기 위해 state 조작하기 (위시리스트) (0) | 2024.06.16 |