[jQuery] .on()
on 메소드 사용
이벤트를 붙여주는 기능이라고 생각하면 쉬움. 브라우저가 클릭과 같은 사용자 액션에 맞춰 이벤트를 생성하면서 미리 정의해둔 핸들러함수를 호출해 준다.
사용법 1
.on( events [, selector ] [, data ], handler )
부모요소.on(이벤트종류명 [, 적용 셀렉터] [, 핸들러함수에 전달할 데이터], 핸들러함수)
아래 예시에서 .on()
는 change
이벤트가 발생하면 input
셀렉터에 로그를 출력하는 핸들러함수
를 붙여주는 역할을 한다. userInfo
로 제한을 뒀기때문에 저장여부의 input
은 변경이 되어도 로그를 출력하지 않는다.
<div id="userGroup">
<div id="userInfo">
<label>아이디</label>
<input type="text" id="userId" name="userId" value="" /><br/>
<label>이름</label>
<input type="text" id="userName" name="userName" value="" /><br/>
</div>
<div id="saved">
<label>저장여부</label>
<input type="checkbox" id="checkYn" /><br/>
</div>
</div>
$('#userInfo').on('change', 'input', () => {
console.log($(event.target).val()); // checkYn은 해당하지 않는다.
});
참고로 .trigger()
는 .on()
과 같은 기능이나 브라우저이벤트(click
, change
등)뿐만 아니라 커스텀이벤트도 처리할수 있다.
사용법 2
.on( events [, selector ] [, data ] )
부모요소.on(이벤트정보 [, 적용 셀렉터] [, 데이터])
events
인수는 키:값 형태로 이벤트와 핸들러함수를 매핑해 줄 수 있다.
위 예시를 두번째 형태로 고치면 아래와 같다.
$('#userInfo').on({
change: function() {
console.log($(event.target).val());
}
}, 'input');
on 메소드 위치
.on()
를 사용하기 위해서는 적용될 셀렉터가 미리 생성되어 있어야 한다. 따라서 HTML 하단에 .on()
을 위치시키거나 document.ready()
를 이용해 셀렉터가 완전히 생성된 이후에 처리가 되도록 한다.
또는 이벤트 위임(Delegated event handlers)
를 사용해 지금은 없지만 추가될 요소에도 영향을 미칠 수 있다.
영향범위
버블효과에 의해 각 요소에 따로 이벤트를 부착하지 않아도 userGroup
요소 하위의 모든 요소들에서 change
이벤트가 발생할 경우 모두 핸들러 함수를 호출하게 된다.
<div id="userGroup">
<div id="userInfo">
<label>아이디</label>
<input type="text" id="userId" name="userId" value="" /><br/>
<label>이름</label>
<input type="text" id="userName" name="userName" value="" /><br/>
<label>좋아하는 과일은?</label>
<select id="fruit" name="fruit">
<option value="apple">apple</option>
<option value="banana">banana</option>
<option value="citrus">citrus</option>
</select>
</div>
<div id="saved">
<label>저장여부</label>
<input type="checkbox" id="checkYn" /><br/>
</div>
</div>
$('#userGroup').on({
change: function() {
console.log($(event.target).val());
}
});
핸들러 함수는 생성되지 않은 요소에도 이벤트를 붙일 수 있다. 아래 html
에 현재 tr
태그는 없지만 자바스크립트로 생성이 되면 그 이후에 이벤트 핸들러가 부착이 되고 클릭 하면 로그를 찍을 수 있게 된다.
<table id="fruits" style="border: 1px solid black; border-collapse: collapse;">
<thead>
<th>과일명</th>
</thead>
<tbody style="font-size: 12px; font-weight: 600;">
</tbody>
</table>
var fruits = ['apple', 'banana', 'citron'];
fruits.forEach((ele) => {
var newTr = $('<tr>', {
css: {
border: '1px solid black'
}
});
var newTd = $('<td>', {
text: ele
});
newTr.append(newTd);
$('#fruits').append(newTr);
});
// tr이 생성된 이후에만 처리될수 있으므로 html 하단 혹은 document.ready() 안에서 위치해야만 이벤트가 붙여진다.
// 아래와 같이 하면 아무 반응이 없음
// $('tbody tr').on('click', () => {
// console.log($(event.target).text());
// })
// tr이 생성된 이후에 이벤트가 붙여지므로 위치는 상관없다.
$('tbody').on('click', 'tr', () => {
console.log($(event.target).text());
})
버블현상이 일어나지 않는 이벤트
참고로 아래 이벤트는 이벤트 위임으로 사용할 수 없지만 직접 요소에 붙일 수는 있다.
jQuery
에서는focusin, focusout
으로 대체가능하지만 원래는 불가능:focus
,blur
- 모든 브라우저에서 불가능:
load
,scroll
,error
- IE 8이하 불가능:
paste
,reset