stateの状態のパターンが「2より大きい場合」のアニメーションの構造について

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

前回のstateが2つしかない場合のアニメーションの設計の考察に続き、今回はstateが4つあるアニメーションについて考察する。つまり、stateの状態のパターンが「2より大きい場合」について。

この場合について考えてみてわかったことだが、stateの状態のパターン数が2なのか、2より大きいのかは、実装の上では本質的な違いがない。何故なら、前回のように2つの段階に切り分けておけば、アニメーションを実行する段階では既に、対象や(どのDOMを動かすのか)、どのようなアニメーションにするのか(開くのか、閉じるのか)は一意に決まっているからだ。逆に言うと、アニメーションを実行する段階で対象と仕様が一意に決まるからこそ、このような2段階切り分けが有効なのだと考えられる。

“stateの状態のパターンが「2より大きい場合」のアニメーションの構造について” の続きを読む

ES5のクラス class もどき prototype

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

ES5 にクラスはない。コンストラクタでインスタンスを作成するが、このコンストラクタも実態は単なる関数。関数を実行してオブジェクトを作っているだけ。

作成されるインスタンスは、プロパティをコンストラクタで定義され、メソッドはそのコンストラクタ.prototypeにあるものを「参照」する。

クラスを extend するためには、プロトタイプチェーンを使って継承する。

メソッドを継承するのは簡単だが、コンストラクタを継承するには少し細かく書く。callで元のコンストラクタを、新しいコンストラクタで初期化する内容を書く部分で実行する。

var Human4 = function (name){
 //プロパティ
 this.name = name;
 //メソッド 
};

//prototypeが大事
Human4.prototype.callOwnName = function(){
 console.log("Human4: my name is " + this.name ); 
 };
//あらたにManクラスを作成
var Man = function(name,job){
	//受けうつぐuman4つまりコンストラクタを、このコンテキストのthisで実行。引数はname
	Human4.call(this,name);
	this.job = job;
};
//Humanを継承
Man.prototype = new Human4();
//Manだけのメソッドを追加
Man.prototype.myJob = function(){console.log("my job is "+ this.job);};

//インスタンスを作成
var nakanishiMan = new Man("nakanishiMan","Web Developper");
nakanishiMan.bark();
console.log(nakanishiMan.job);
nakanishiMan.myJob();

jQueryのOnの使い方

jQueryのonを使うことで、複数のイベントを一度に付加できる。また脱着の自由度も高い。そのためonclickではなく、基本的にONを使う。

onイベントの2つめの引数として{key:値}を渡すと、ハンドラが受け取ることができ、e.date.keyで取り出すことが出来る。

{key:値,key2:値}で複数の値を渡すことも出来る。

See the Pen jQuery On by nakanishi (@nakanishi) on CodePen.

ES5, CoffeeScript, ES6の記法の違い

ES5, CoffeeScript, ES6の記法の違いが混乱するのでまとめた。

ES5 CoffeeScript ES6
参考資料 詳しい
標準ブラウザで 読める 読めない (要トランスコンパイル) 読めないものも多くある (実務レベルでは要トランスコンパイル/主としてBabelを用いる)
 記法デモ Class構文 JQuery.cssの書き方 Class構文 ES5と6の違い
セミコロン いる いらない いる
function(){内容} function(){内容} ()=> 改行インデント 内容 ()=>{内容}
 function(引数){内容}   function(引数){内容} (引数)=> 改行インデント  内容  (引数)=>{内容}
関数の実行 call(); call()

引数がないときは必ず()が必要

call();
関数の実行(引数あり) call(“start”); call “start”

引数があるときは()を省略可能

call(“start”);

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の違いについて

次の記事を参照

 

ES6のクラス構文

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

class クラス名/冒頭は大文字  { 内容 }

内容にはコンストラクタとメンバ変数とメソッドを書く。

  • constructor(引数1,引数2) { this.引数1; this.引数2; this.call();等々}
  • メソッドはclassの中、constructorの外に書く call(){}

クラスを使うときはnew クラス名()、もしくはvar 変数名 = new クラス名()

new クラス名()をすると、コンストラクタに書かれた内容が実行される。変数名に代入すると、オブジェクトが変数に入る。

機能単位でクラスを作って、newをして実行するのが良い

最終的には機能毎にファイルを分けて、クラスを作成し、export/importをして、必要な時にnewで呼び出すのがよい。

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関係は微妙に異なるようなので注意
  • クラス構文が使えるのはどちらも共通しているが、書き方が少し異なるようだ

CodePenでVelocity.jsを使う

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

CodePenは各種JSライブラリを使用することができる。今回はアニメーションに特化したライブラリ「Velocity.js」を使ってみた。

Velocity自体がjQueryに依存しているので、まずjQueryをaddし、次にVelocityをaddする。基本的にCDNから引っ張ってくればよい。

%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-0-14-19