イベントターゲットの比較

イベントハンドラーを書くときに、どのイベントターゲットを調べればいいのか迷うことはよくあります。この記事では、ターゲットプロパティの使い方を明確にします。

検討すべきターゲットは 5 つあります。

プロパティ 定義場所 目的
event.target DOM Event Interface このイベントを発行した呼び出しの左側にある DOM 要素。
event.currentTarget DOM Event Interface その EventListeners が現在処理されている EventTarget です。イベントキャプチャとバブリングが発生すると、この値は変化します。
event.relatedTarget DOM MouseEvent Interface イベントのセカンダリーターゲットを特定します。
event.explicitOriginalTarget Event.webidl Non-Standard イベントが無名の境界通過以外の理由で再ターゲットされた場合、再ターゲットが発生する前にターゲットに設定されます。例えば、マウスイベントがテキストノードの上で発生した場合、その親ノードに再ターゲットされます(バグ 185889)。その場合、 .target は親ノードを表示し、.explicitOriginalTarget はテキストノードを表示します。 .originalTarget とは異なり、.explicitOriginalTarget には無名コンテンツが含まれることはありません。
event.originalTarget Event.webidl Non-Standard 再ターゲットされる前の、イベントの本来のターゲットです。詳細は Anonymous Content#Event_Flow_and_Targeting を参照してください。
event.composedTarget Event.webidl Non-Standard Shadow DOM から合成する前の、イベントの元の非ネイティブターゲット。

explicitOriginalTargetoriginalTarget の使用

Note: これらのプロパティは、 Mozilla ベースのブラウザーでのみ利用可能です。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>Comparison of Event Targets</title>
  <style>
    table {
      border-collapse: collapse;
      height: 150px;
      width: 100%;
    }
    td {
      border: 1px solid #ccc;
      font-weight: bold;
      padding: 5px;
      min-height: 30px;
    }
    .standard {
      background-color: #99ff99;
    }
    .non-standard {
      background-color: #902D37;
    }
    </style>
</head>
<body>
  <table>
    <thead>
      <tr>
        <td class="standard">Original target dispatching the event <small>event.target</small></td>
        <td class="standard">Target who's event listener is being processed <small>event.currentTarget</small></td>
        <td class="standard">Identify other element (if any) involved in the event <small>event.relatedTarget</small></td>
        <td class="non-standard">If there was a retargeting of the event for some reason <small> event.explicitOriginalTarget</small> contains the target before retargeting (never contains anonymous targets)</td>
        <td class="non-standard">If there was a retargeting of the event for some reason <small> event.originalTarget</small> contains the target before retargeting (may contain anonymous targets)</td>
      </tr>
    </thead>
    <tr>
      <td id="target"></td>
      <td id="currentTarget"></td>
      <td id="relatedTarget"></td>
      <td id="explicitOriginalTarget"></td>
      <td id="originalTarget"></td>
    </tr>
  </table>
  <p>Clicking on the text will show the difference between explicitOriginalTarget, originalTarget, and target</p>
  <script>
    function handleClicks(e) {
      document.getElementById('target').innerHTML = e.target;
      document.getElementById('currentTarget').innerHTML = e.currentTarget;
      document.getElementById('relatedTarget').innerHTML = e.relatedTarget;
      document.getElementById('explicitOriginalTarget').innerHTML = e.explicitOriginalTarget;
      document.getElementById('originalTarget').innerHTML = e.originalTarget;
    }

    function handleMouseover(e) {
      document.getElementById('target').innerHTML = e.target;
      document.getElementById('relatedTarget').innerHTML = e.relatedTarget;
    }

    document.addEventListener('click', handleClicks, false);
    document.addEventListener('mouseover', handleMouseover, false);
</script>
</body>
</html>

targetrelatedTarget の使用

mouseover イベントの relatedTarget プロパティは、マウスが以前乗っていたノードを保持します。 mouseout イベントでは、マウスが移動した先のノードが保持されます。

イベント種別 event.target event.relatedTarget
mouseover ポインティングデバイスが入った EventTarget ポインティングデバイスがでた EventTarget
mouseout ポインティングデバイスがでた EventTarget ポインティングデバイスが入った EventTarget

<hbox id="outer">
  <hbox id="inner"
        onmouseover="dump('mouseover ' + event.relatedTarget.id + ' > ' + event.target.id + '\n');"
        onmouseout="dump('mouseout  ' + event.target.id + ' > ' + event.relatedTarget.id + '\n');"
        style="margin: 100px; border: 10px solid black; width: 100px; height: 100px;" />
</hbox>