다음은 사람들이 문제를 더 잘 이해하고 해결하는 데 도움이 될 수있는 몇 가지 예입니다.
TL; DR
on*이벤트 핸들러 (예 onclick: 버튼 요소의 속성) : 이벤트를 취소하려면 false를 반환합니다.
addEventListener다른 API이므로 반환 값 (예 false:)은 무시됩니다. 사용 event.preventDefault().
onclick="<somejs>"<somejs>onclick 함수의 본문에 포함되어 있기 때문에 잠재적 인 혼란 이 있습니다.
- 브라우저 devtools
getEventListenersAPI를 사용 하여 이벤트 핸들러가 예상대로 작동하지 않는 경우 문제를 해결하기 위해 이벤트 리스너가 어떻게 보이는지 확인합니다.
예
이 예제는 링크 가있는 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();onclickmyHandlerFunc
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모두에 대한 이벤트를 취소 한다는 것을 의미하는 것 같습니다 .addEventListeneronclick
그러나 연결된 정의 event-handler를 살펴보면 다음을 참조하십시오.
이벤트 핸들러에는 항상 "on"으로 시작하는 이름이 있으며 그 뒤에 해당 이벤트 이름이옵니다.
...
이벤트 핸들러는 두 가지 방법 중 하나로 노출됩니다.
모든 이벤트 핸들러에 공통적 인 첫 번째 방법은 이벤트 핸들러 IDL 속성을 사용하는 것입니다.
두 번째 방법은 이벤트 핸들러 컨텐츠 속성입니다. HTML 요소의 이벤트 처리기와 Window 개체의 일부 이벤트 처리기는 이러한 방식으로 노출됩니다.
https://www.w3.org/TR/html5/webappapis.html#event-handler
따라서 return false이벤트 취소는 실제로 onclick(또는 일반적으로 on*) 이벤트 핸들러 에만 적용되고 addEventListener다른 API 를 통해 등록 된 이벤트 핸들러 에는 적용되지 않는 것 같습니다 .
때문에 addEventListenerAPI는 HTML5 스펙 (단지이 적용되지 않습니다 on*이벤트 핸들러)들이 붙어 있다면 ... 그것은 혼란을 덜 될 on*자신의 예제 형식의 이벤트 핸들러.