event.currentTargetとevent.targetの違い

See the Pen used target by nakanishi (@nakanishi) on CodePen.

event.target と event.currentTargetは違う

イベントが発生した時に、イベントリスナーでイベントオブジェクトを取得することができるが、このイベントリスナーの event.target と event.currentTarget は「異なる性質」を持つので注意したい。

確認:イベントリスナーとは

イベントリスナーとは、イベントターゲット(HTMLの各種要素=ノード等)に対して、イベント(clickやhover)が発生した際に実行する「関数、もしくはオブジェクト」を関連付ける仕組みのこと。具体的には、あるdivがマウスオーバーされた時に特定の関数を実行する、といった機能を実装する際に使われる。

//ES6です
'use strict';

class AddHover {
  constructor(target) {
    this.target = target;
    this.hover(this.target);
    console.log("new"+this.target);
  }
  
  hover(target) {
    let $hoverTarget = $(target);
    let rolloverClass = 'hover';
    $hoverTarget.hover(
    //ここがイベントリスナー
      (event) => {
        $(event.currentTarget).addClass(rolloverClass);    
      },
      (event) => {
        $(event.currentTarget).removeClass(rolloverClass); 
      }
    )
  }
}

イベントオブジェクトとは

イベントリスナーで指定する関数の第一引数に、イベント・オブジェクトが入る。(event) => {} はfunction(event){}と同じ意味。

//ES6です
$hoverTarget.hover(
 (event) => {
    $(event.currentTarget).addClass(rolloverClass);    
    },
  (event) => {
    $(event.currentTarget).removeClass(rolloverClass); 
  }
)

event.currentTargetとevent.targetの違い

See the Pen used target by nakanishi (@nakanishi) on CodePen.

やっと本題だが、event.currentTargetは、イベントが付けられたノードを返し、event.targetは実際にイベントが発生したノードを返す。

上記のコードデモでは、nakaと書かれたdivはcurrentTargetを指定しているため、正常に動くが、その下のdivではラテン語のダミーテキストにマウスオーバーをするとテキスト部分だけに色が付いてしまい意図した挙動とならない。こちらはtargetを指定しているためだ。

targetはイベントリスナーを付けたノードではなく、マウスオーバー「イベントが発生したノードそのもの」を返すために、今回の例ではダミーテキストが入った<p>ノードを返す。結果としてバックグラウンドカラーが、pの部分だけに指定されてしまう。

実装時には、HTMLの構造、及びクラス付に注意しながらtargetとcurrentTargetを使い分ける必要がある。

ES6 + jQuery でマウスホバーを実装する

See the Pen used es6 hover class new by nakanishi (@nakanishi) on CodePen.

AddHoverクラスの中に機能を実装し、ページ読み込み時にAddHoverクラスをnewでたたく。

注意:event.targetとevent.currentTargetの違いについて

次の記事を参照

 

CodePenでES6以上をBabelでコンパイルして使う

ES6とBabel

ES6ではclass構文が使えるようになり、素直なオブジェクト指向プログラミングが可能になったが、ES6は現状サポートしていないブラウザもある。そのためES6で書いたスクリプトはBabelを使ってES5にトランスコンパイルして使用する。

CodePenとBabel

CodePenではBabelをプリプロセッサーとして用いることができ、これによってES6記法のJSをES5記法に変換することができる。

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-11-13-14-31-37

ES6のfunction記法抜粋

ES6はarrow functionが使える。これとjQueryを組み合わせた記法を以下に示す。

特に、arrow functionとjQueryのhoverメソッドを用いる場合にthisの扱いに注意することがポイントである。

See the Pen NbNaXY by nakanishi (@nakanishi) on CodePen.

CoffeeScriptとの違い

CofeeScriptの開発はほぼ停止しているらしく、かつ一番必要とされていたクラス構文がES6で実装されたことから、基本的にはES6を中心に書いていけばよいものと思われる。

  • {}も()も;も基本的に必要で、通常のJSと同じ。
  • インデントは内容には関係しない (CoffeeScriptはインデントによって内容が変わる)
  • import,export,require関係は微妙に異なるようなので注意
  • クラス構文が使えるのはどちらも共通しているが、書き方が少し異なるようだ