다음은 사람들이 문제를 더 잘 이해하고 해결하는 데 도움이 될 수있는 몇 가지 예입니다.
TL; DR
on*
이벤트 핸들러 (예 onclick
: 버튼 요소의 속성) : 이벤트를 취소하려면 false를 반환합니다.
addEventListener
다른 API이므로 반환 값 (예 false
:)은 무시됩니다. 사용 event.preventDefault()
.
onclick="<somejs>"
<somejs>
onclick 함수의 본문에 포함되어 있기 때문에 잠재적 인 혼란 이 있습니다.
- 브라우저 devtools
getEventListeners
API를 사용 하여 이벤트 핸들러가 예상대로 작동하지 않는 경우 문제를 해결하기 위해 이벤트 리스너가 어떻게 보이는지 확인합니다.
예
이 예제는 링크 가있는 click
이벤트 에만 해당 <a>
되지만 대부분의 이벤트 유형에 대해 일반화 할 수 있습니다.
js-some-link-hook
모달을 열고 페이지 탐색이 발생하지 않도록 방지하려는 클래스가있는 앵커 (링크)가 있습니다.
아래 예제는 MacOS Mojave의 google chrome (71)에서 실행되었습니다.
한 가지 주요 함정은 onclick=functionName
사용하는 것과 동일한 동작을 가정하는 것 입니다.addEventListener
자바 스크립트가 활성화되었을 때 자바 스크립트로 처리하려는 앵커 태그 (링크)가 있다고 가정 해 보겠습니다. 클릭했을 때 브라우저가 링크를 따라가는 것을 원하지 않습니다 ( "기본 동작 방지"동작).
<a href="https://www.example.com/url/to/go/to/when/no/javascript"
class="js-some-link-hook">click me!</a>
onclick 속성
function eventHandler (event) {
alert('eventHandler ran');
return false;
}
function addEventListenerToElement () {
var link = document.querySelector('.js-some-link-hook');
link.setAttribute('onclick', eventHandler);
}
addEventListenerToElement();
그런 다음 브라우저 devtools 콘솔에서 실행합니다.
var el = document.querySelector('a.js-some-link-hook'),
listener = getEventListeners(el).click[0].listener;
console.log(''+listener);
... 그리고 다음을 볼 수 있습니다.
function onclick(event) {
function eventHandler (event) {alert('eventHandler ran'); return false;}
}
이것은 전혀 작동하지 않습니다. onclick=
핸들러 함수를 사용할 때 다른 함수로 래핑됩니다.
함수 정의가 포함되어 있지만 호출하지 않고 함수 참조를 지정했기 때문에 호출되지 않았 음을 알 수 있습니다. 즉 , 요소를 클릭 할 때 실행 되는지 확인할 필요가 onclick="functionName()"
없습니다 .onclick="functionName"
functionName
또한 내 함수가 호출되고 내 함수 onclick
가 false를 반환하더라도 이벤트를 '취소'하는 데 필요한 false 값을 반환하지 않음을 알 수 있습니다.
이 문제를 해결하기 위해 에서 반환 값 (false) 을 반환 하도록 설정할 onclick
수 있습니다 .return myHandlerFunc();
onclick
myHandlerFunc
return false;
from 을 제거하고 to be를 myHandlerFunc
변경할 onclick
수도 myHandlerFunc(); return false;
있지만 핸들러 함수에서 로직을 함께 유지하려는 경우 의미가 떨어집니다.
참고 설정 onclick
자바 스크립트와 함께 당신이 설정 될 때, onclick
오히려 (내 예와 같은) 자바 스크립트와보다 HTML에 직접적으로 onclick
속성 값은 문자열 형식과 모든 작품입니다. onclick
자바 스크립트를 사용하여 설정 하는 경우 입력에주의해야합니다. 당신이 말한다면 element.setAttribute('onclick', myHandlerFunc())
myHandlerFunc
지금 실행되고 결과가 아니라 클릭 할 때마다 실행하는 것보다 ... 속성에 저장됩니다. 대신 속성 값이 문자열로 설정되어 있는지 확인해야합니다. element.setAttribute('onclick', 'return myHandlerFunc();')
이제 어떻게 작동하는지 확인 했으므로 원하는 작업을 수행하도록 코드를 수정할 수 있습니다. 예시를위한 이상한 예 (이 코드를 사용하지 마세요) :
function eventHandler (e) {
alert('eventHandler ran');
console.log(e);
return false;
}
function addEventListenerToElement () {
var link = document.querySelector('.js-some-link-hook');
link.setAttribute('onclick', 'return ('+eventHandler+')(event);');
}
addEventListenerToElement();
eventHandler 함수 정의를 문자열로 래핑 한 것을 볼 수 있습니다. 특히 : 앞에 return 문이있는 자체 실행 함수입니다.
다시 크롬 devtools 콘솔에서 :
var el = document.querySelector('a.js-some-link-hook'),
listener = getEventListeners(el).click[0].listener;
console.log(''+listener);
... 표시 :
function onclick(event) {
return (function eventHandler (e) {
alert('eventHandler ran');
console.log(e);
return false;
})(event);
}
... 그래, 작동합니다. 링크를 클릭하면 경고가 표시되고 경고를 해제하면 페이지가 아무 곳도 탐색하지 않거나 새로 고쳐지지 않습니다.
참고 사항 onclick
...event
이벤트 시점에 매개 변수 를 받아 활용하려면 "event"라는 이름을 참고해야합니다. 이름을 사용하여 핸들러 내에서 액세스 할 수 있습니다 event
(부모 onclick
함수 범위 를 통해 사용 가능 ). 또는 event
매개 변수 (테스트에 더 좋음) 로 취 onclick="return myEventHandler(event);"
하거나 이전 예제에서 볼 수있는 것처럼 핸들러를 구성 할 수 있습니다 .
addEventListener
function eventHandler (ev) {
alert('eventHandler ran');
console.log(ev);
return false;
}
function addEventListenerToElement () {
var link = document.querySelector('.js-some-link-hook');
link.addEventListener('click', eventHandler, false);
}
addEventListenerToElement();
브라우저 개발 도구 :
var el = document.querySelector('a.js-some-link-hook'),
listener = getEventListeners(el).click[0].listener;
console.log(''+listener);
결과:
function eventHandler (ev) {
alert('eventHandler ran');
console.log(ev);
return false;
}
따라서 이미 차이를 볼 수 있습니다. 함께 addEventListener
우리는에 싸여되지 않습니다 onclick
기능. 핸들러는 event
매개 변수를 직접 수신 하므로 원하는대로 호출 할 수 있습니다. 또한 우리 return false
는 여기에서 "최상위 수준"에 있으며 with와 같은 추가 return 문을 추가하는 것에 대해 걱정할 필요가 없습니다 onclick
.
그래서 작동해야 할 것 같습니다. 링크를 클릭하면 경고가 표시됩니다. 경고를 해제하면 페이지가 탐색 / 새로 고침됩니다. 즉, 이벤트가 false를 반환하여 취소되지 않았습니다.
사양을 조회하면 (하단의 리소스 참조) addEventListener에 대한 콜백 / 핸들러 함수가 반환 유형을 지원하지 않음을 알 수 있습니다. 원하는 것은 무엇이든 반환 할 수 있지만 브라우저 API / 인터페이스의 일부가 아니기 때문에 아무 효과가 없습니다.
솔루션 : event.preventDefault()
대신 사용 return false;
...
function eventHandler (ev) {
ev.preventDefault();
alert('eventHandler ran');
}
function addEventListenerToElement () {
var link = document.querySelector('.js-some-link-hook');
link.addEventListener('click', eventHandler, false);
}
addEventListenerToElement();
브라우저 개발 도구 ...
var el = document.querySelector('a.js-some-link-hook'),
listener = getEventListeners(el).click[0].listener;
console.log(''+listener);
준다 ...
function eventHandler (ev) {
ev.preventDefault();
alert('eventHandler ran');
}
... 예상대로.
다시 테스트 :
- 링크를 클릭하십시오.
- 경고를 받으십시오.
- 경고 해제.
- 페이지 탐색이나 새로 고침이 발생 하지 않습니다 . 우리가 원하는 것입니다.
따라서 false를 반환 하는 데 addEventListener
사용 event.preventDefault()
하면 아무 작업도 수행되지 않습니다.
자원
html5 사양 ( https://www.w3.org/TR/html5/webappapis.html#events )은 onclick
및 addEventListener
예제에서 모두 사용 하고 다음과 같이 말하기 때문에 혼란 스럽습니다 .
이벤트 핸들러 H 및 이벤트 객체 E에 대한 이벤트 핸들러 처리 알고리즘은 다음과 같습니다.
...
- 다음과 같이 반환 값을 처리합니다.
...
반환 값이 Web IDL 부울 false 값이면 이벤트를 취소합니다.
따라서 및 return false
모두에 대한 이벤트를 취소 한다는 것을 의미하는 것 같습니다 .addEventListener
onclick
그러나 연결된 정의 event-handler
를 살펴보면 다음을 참조하십시오.
이벤트 핸들러에는 항상 "on"으로 시작하는 이름이 있으며 그 뒤에 해당 이벤트 이름이옵니다.
...
이벤트 핸들러는 두 가지 방법 중 하나로 노출됩니다.
모든 이벤트 핸들러에 공통적 인 첫 번째 방법은 이벤트 핸들러 IDL 속성을 사용하는 것입니다.
두 번째 방법은 이벤트 핸들러 컨텐츠 속성입니다. HTML 요소의 이벤트 처리기와 Window 개체의 일부 이벤트 처리기는 이러한 방식으로 노출됩니다.
https://www.w3.org/TR/html5/webappapis.html#event-handler
따라서 return false
이벤트 취소는 실제로 onclick
(또는 일반적으로 on*
) 이벤트 핸들러 에만 적용되고 addEventListener
다른 API 를 통해 등록 된 이벤트 핸들러 에는 적용되지 않는 것 같습니다 .
때문에 addEventListener
API는 HTML5 스펙 (단지이 적용되지 않습니다 on*
이벤트 핸들러)들이 붙어 있다면 ... 그것은 혼란을 덜 될 on*
자신의 예제 형식의 이벤트 핸들러.