JavaScript의 인라인 이벤트 처리기에 이벤트를 인수로 전달하는 방법은 무엇입니까?


103
// this e works
document.getElementById("p").oncontextmenu = function(e) {
    e = e || window.event;
    var target = e.target || e.srcElement;
    console.log(target);
};

// this e is undefined
function doSomething(e) {
    e = e || window.event;
    var target = e.target || e.srcElement;
    console.log(target);
}
<p id="p" onclick="doSomething(e)">
    <a href="#">foo</a>
    <span>bar</span>
</p>

비슷한 질문이 몇 가지 있습니다.

하지만 내 코드에서, 내가 좋아하는, 클릭 됐어요 자식 요소 얻으려고 a또는span .

그렇다면 event이벤트 핸들러에 인수 로 전달하는 올바른 방법은 무엇 입니까? 아니면 인수를 전달하지 않고 핸들러 내부에 이벤트를 가져 오는 방법은 무엇입니까?

편집하다

addEventListener및 jQuery을 (를) 알고 inline있습니다. 이벤트를 이벤트 처리자 에게 전달하기위한 솔루션을 제공하십시오 .



5
addEventListener로 전환하는 대신 인라인 이벤트 핸들러를 사용하는 좋은 이유가 있습니까? en.wikipedia.org/wiki/Unobtrusive_JavaScript
— Xotic750

2
@ Xotic750 예, 예를 들어 ajax를 통해 html을 동적으로로드하거나 다시로드 할 때마다 수동으로 다시 바인딩 할 필요가 없습니다.
— Wadih M.

답변:


166

event객체 를 전달하려면 :

<p id="p" onclick="doSomething(event)">

클릭 된 자식을 가져 오기 위해 element( event매개 변수 와 함께 사용해야합니다 .

function doSomething(e) {
    e = e || window.event;
    var target = e.target || e.srcElement;
    console.log(target);
}

element자체 전달 (DOMElement) :

<p id="p" onclick="doThing(this)">

jsFiddle에서 라이브 예제보기


11
(그리고 궁금 누군가를 위해 : 예, 이것은 일부 [예를 들어 파이어 폭스,] 글로벌 가지고 있지 않더라도, 등 크롬, 파이어 폭스, 작업을 수행합니다 event. 객체를 그건 dom0에서 핸들러가 호출되는 상황이 있기 때문에 event객체를 , [일부 브라우저에서는] 전역 적이 지 않더라도.)
— TJ Crowder 2013 년

thispaspan
— 는를

3
'이벤트'를 전달하는 것은 지원되는 경우 내가 아는 유일한 방법입니다. "this"구문 분석은이 상황에서 소용이 없습니다
— Xotic750

5
@ user1643156 매우 중요합니다. 매개 변수의 이름은 정확히 "event"로 지정되어야합니다.
— The-null-Pointer-

1
Wadih M.의 대답은 이것보다 훨씬 낫습니다. 이것은 오해의 소지가 있습니다 (그와 유사한 다른 것들처럼), 사람들이 "(event)"매개 변수를 함수 호출에 넣어야한다고 믿게 만듭니다. 실제로 JavaScript는 호출 된 함수 내에서 이미 "event"매개 변수를 사용할 수 있습니다. 그래서 그것을 선언 할 필요가 없습니다 (실제로 전달되지 않았기 때문에 변수 이름을 변경하는 것이 아무런 차이가 없다는 것을 깨닫는 데 며칠이 걸렸습니다). 또한 거기에 주어진 설명은 JS가 왜 그렇게 작동하는지에 대한 의구심을 일축합니다 (아마도 그렇게해서는 안되지만 판단 할 수는 없습니다 ...)
— 안되지만

15

인라인 이벤트는 함수로 실행되므로 단순히 인수 를 사용할 수 있습니다 .

<p id="p" onclick="doSomething.apply(this, arguments)">

과

function doSomething(e) {
  if (!e) e = window.event;
  // 'e' is the event.
  // 'this' is the P element
}

허용되는 답변에 언급 된 '이벤트'는 실제로 함수에 전달 된 인수의 이름입니다. 글로벌 이벤트와는 아무 관련이 없습니다.


좋은 팁. 사람들은 웹 구성 요소를 채택 시작하는 경우 call()와 apply()주류 JS 프레임 워크에서 사용할 수있는 기능을 데이터 바인딩을 모방 필수적 증명합니다. 한 가지 추가 트릭은 Object.assign(this.querySelector('my-btn'), this)웹 구성 요소 및 데이터 바인딩 내부 와 유사한 작업을 수행하는 것 입니다. 인라인 이벤트에서 상위 웹 구성 요소 클래스의 모든 메서드에 액세스 할 수 있습니다 onclick="toggleBtnActive.call(this, true)".
— Adrian Moisa

8

통과 할 필요가 없습니다. this이미event 기본적으로 자동으로 전달 된 객체 있으며 event.target여기에는 해당 객체가있는 객체가 포함 됩니다. 구문을 가볍게 할 수 있습니다.

이:

<p onclick="doSomething()">

이것으로 작동합니다 :

function doSomething(){
  console.log(event);
  console.log(event.target);
}

인스턴스화 할 필요가 없습니다. event개체 이미 존재합니다. 그것을 시도하십시오. 그리고 event.target이전에 "this"라고 언급했던 전체 객체를 포함합니다.

이제 코드 어딘가에서 동적으로 doSomething ()을 트리거하면 event정의되지 않은 것을 알 수 있습니다. 클릭 이벤트에서 트리거되지 않았기 때문입니다. 따라서 이벤트를 인위적으로 트리거하려면 dispatchEvent다음을 사용하십시오 .

document.getElementById('element').dispatchEvent(new CustomEvent("click", {'bubbles': true}));

그럼 doSomething()볼 것이다event 과 event.target평소에 따라!

this모든 곳 을 통과 할 필요가 없으며 기능 시그니처에 배선 정보가 없도록 유지하고 작업을 단순화 할 수 있습니다.


적어도 IE11에서는 이것이 사실이 아닙니다. 기본 인수가 없습니다.
— cskwg

1
@cskwg IE11에서도 작동합니다. 이전 버전과의 호환성을 위해 필요하므로 모든 주요 브라우저에서 작동합니다. 대답에서 언급했듯이 이벤트가 존재하는 유일한 시나리오 인 이벤트에서 자바 스크립트 함수가 실행되는 경우에만 함수 내에서 쉽게 액세스 할 수있는 "이벤트"라는 개체가 있습니다. 함수 프로토 타입에 추가 배선을 전달합니다. 방금 내 컴퓨터에서 onclick 이벤트에 대한 IE11 테스트를 수행했으며 'event'변수에 "PointerEvent 개체"가 포함되어 있습니다.
— Wadih M.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.