読者です 読者をやめる 読者になる 読者になる

event.curretTargetとevent.targetの違い

javascript

新人の真崎です。 今回も短めの記事で行きます。

イベントが発火した要素の取得の仕方

イベントが発火したときに、イベントリスナにイベントオブジェクト(最初の引数)が渡されます。 このオブジェクトにどの要素でイベントが発火したのか示すプロパティが2種類あります。 その2種類event.currentTargetとevent.targetの違いについて見て行きたいと思います。

エレメント.addEventListener(イベント, function(e) {}, false);
$(セレクタ).on(イベント, function(e) {});

event.currentTarget

イベントリスナをバインドした要素をイベントが通過した時の要素(イベントリスナがバインドされてる要素自身)を表します

event.target

イベントが発生した要素を表します。

以下の例で説明します。 青い部分をクリックすると、".outer"にバインドしたイベントリスナに「currentTarget=".outer"」、「target=".outer"」なイベントオブジェクトが渡されます。 他の色の部分をクリックすると、".inner"にバインドしたイベントリスナに「currentTarget=".inner"」、「target=".inner"」なイベントオブジェクト、".outer"にバインドしたイベントリスナに「currentTarget=".outer"」、「target=".inner"」なイベントオブジェクトが渡されます。

<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<style type="text/css">
.outer {
    width: 100px;
    height: 100px;
    background: blue;
}
.inner {
    width: 50px;
    height: 25px;
}
.inner:nth-child(1) {
    background: pink;
}
.inner:nth-child(2) {
    background: purple;
}
.inner:nth-child(3) {
    background: orange;
}
.inner:nth-child(4) {
    background: green;
}
</style>
<script type="text/javascript">
$(document).on("click", ".outer", function(e) {console.log(e.currentTarget, e.target);});
$(document).on("click", ".inner", function(e) {console.log(e.currentTarget, e.target);});
</script>
</head>

<body>
    <div class="outer">
        <div class="inner"></div>
        <div class="inner"></div>
        <div class="inner"></div>
        <div class="inner"></div>
    </div>
</body>
</html>

まとめ

event.currentTargetとevent.targetの違いについて見てみました。 currentTarget=バインドした要素、target=イベントが発生した要素と覚えておくと簡単かと思います。 currentTargetのほうがバインドした要素を表しているのでイベントリスナを書くときには、わかりやすいと思います。

underscore.jsで気になる関数(Functions、Objects、Utility、Chaining編)

javascript underscore.js

前回の続きです。今日はUnderscore.jsのFunctions、Objectsを中心に見ていきます。

Functions

FPぽいことするのに便利な関数が揃ってます。

_.memoize(function, [hashFunction])

メモ化関数です。関数の計算結果を記憶しておいて、再計算のコストを低くしてくれます。フィボナッチ数列を計算するのに便利そうです。

var fibonacci = _.memoize(function(n) {
  return n < 2 ? n: fibonacci(n - 1) + fibonacci(n - 2);
});

_.once(function)

関数を一度しか計算しない。初期化処理とかに便利そうです。

var initialize = _.once(createApplication);
initialize();
initialize();
// Application is only created once.

_.after(count, function)

count回関数が呼び出されて初めて、関数が実行されます。非同期の処理実行後に処理を行いたいときに便利そうです。

var renderNotes = _.after(notes.length, render);
_.each(notes, function(note) {
  note.asyncSave({success: renderNotes});
});
// renderNotes is run once, after all notes have saved.

_.wrap(function, wrapper)

関数の前後に処理を行えます。pythonのdecoratorぽいことができそう?

var hello = function(name) { return "hello: " + name; };
hello = _.wrap(hello, function(func) {
  return "before, " + func("moe") + ", after";
});
hello();
=> 'before, hello: moe, after'

_.compose(*functions)

関数合成をしてくれる関数です。かっこたくさん書かなくていいのは、楽です。

var greet    = function(name){ return "hi: " + name; };
var exclaim  = function(statement){ return statement.toUpperCase() + "!"; };
var welcome = _.compose(greet, exclaim);
welcome('moe');
=> 'hi: MOE!'

Objects

_.omit(object, *keys)

keysに指定したプロパティを除外してくれます。chainで使うと便利です。

_.omit({name: 'moe', age: 50, userid: 'moe1'}, 'userid');
=> {name: 'moe', age: 50}

_.defaults(object, *defaults)

デフォルトのプロパティを設定してくれます。

var iceCream = {flavor: "chocolate"};
_.defaults(iceCream, {flavor: "vanilla", sprinkles: "lots"});
=> {flavor: "chocolate", sprinkles: "lots"}

_.tap(object, interceptor)

_chainといっしょに使うと便利です。計算途中の確認に使えます。

_.chain([1,2,3,200])
  .filter(function(num) { return num % 2 == 0; })
  .tap(alert)
  .map(function(num) { return num * num })
  .value();
=> // [2, 200] (alerted)
=> [4, 40000]

Utility

_.result(object, property)

objectのpropertyが関数なら結果を返して、値ならその値を返してくれます。

var object = {cheese: 'crumpets', stuff: function(){ return 'nonsense'; }};
_.result(object, 'cheese');
=> "crumpets"
_.result(object, 'stuff');
=> "nonsense"

Chaining

underscore関数がメソッドチェーンできるので便利です。

var stooges = [{name: 'curly', age: 25}, {name: 'moe', age: 21}, {name: 'larry', age: 23}];
var youngest = _.chain(stooges)
  .sortBy(function(stooge){ return stooge.age; })
  .map(function(stooge){ return stooge.name + ' is ' + stooge.age; })
  .first()
  .value();
=> "moe is 21"

まとめ

2回にわたって、javascriptのユーティリティライブラリであるunderscore.jsのおもしろそうな関数の紹介を行いました。 underscore.jsは、ファイルサイズが小さく(minify&gzipで4.9kb)、実績も豊富(bakcbone.jsの依存ライブラリなのでHulu、foursquareなど)、ドキュメントもわかりやすく、おすすめです。

underscore.jsで気になる関数(collections、arrays編)

javascript underscore.js

2回目にして、もうネタ切れ気味になってきた新人の真崎です。

ネタ切れ気味なので、今日は軽めにUnderscore.jsで気に入ってる関数を幾つか紹介します。

Collections

一般的なmap・reduce・filter系ですが、jsのmap関数はArrayのメソッドだったりするので、Hashにも適用できるのは便利です。特に便利だと思うものをピックアップします。

_.pluck(list, propertyName)

プロパティ名に指定したものをmapしてくれます。

var stooges = [{name: 'moe', age: 40}, {name: 'larry', age: 50}, {name: 'curly', age: 60}];
_.pluck(stooges, 'name');
=> ["moe", "larry", "curly"]

_.groupBy(list, iterator, [context])系

iteratorの返り値でグルーピングしてくれます。

_.groupBy([1.3, 2.1, 2.4], function(num){ return Math.floor(num); });
=> {1: [1.3], 2: [2.1, 2.4]}

_.groupBy(['one', 'two', 'three'], 'length');
=> {3: ["one", "two"], 5: ["three"]}

var stooges = [{name: 'moe', age: 40}, {name: 'larry', age: 50}, {name: 'curly', age: 60}];
_.indexBy(stooges, 'age');
=> {
  "40": {name: 'moe', age: 40},
  "50": {name: 'larry', age: 50},
  "60": {name: 'curly', age: 60}
}

_.countBy([1, 2, 3, 4, 5], function(num) {
  return num % 2 == 0 ? 'even': 'odd';
});
=> {odd: 3, even: 2}

Arrays

_.without(array, [*values])

arrayからvaluesに含まれるものを除外したArrayを返してくれます。chainで使うと便利です。

_.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
=> [2, 3, 4]

_.union(*arrays)

和を取ってくれます

_.union([1, 2, 3], [101, 2, 1, 10], [2, 1]);
=> [1, 2, 3, 101, 10]

_.intersection(*arrays)

積を取ってくれます

_.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]);
=> [1, 2]

_.difference(array, *others)

差を取ってくれます。処理の前後で追加・削除の検出に便利です。

_.difference([1, 2, 3, 4, 5], [5, 2, 10]);
=> [1, 3, 4]

_.uniq(array, [isSorted], [iterator])

重複を取ってくれます

_.uniq([1, 2, 1, 3, 1, 4]);
=> [1, 2, 3, 4]

_.range([start], stop, [step])

一般的なrange関数です

_.range(10);
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
_.range(1, 11);
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
_.range(0, 30, 5);
=> [0, 5, 10, 15, 20, 25]
_.range(0, -10, -1);
=> [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
_.range(0);
=> []

一旦まとめ

Functions、Objects、Utilityにも便利な関数がたくさんあるのですが、長くなりそうなので、今日はこのへんで。

Collections、Arraysには最近の言語だと標準関数で備わってるものが多いですが、今のjsだと使いにくいものも多いので、こういったライブラリで補完すると大変楽です。

underscore.jsは、一般的に使われてる便利なutilityライブラリです。聞いたことあるけど、まだ使ってないって方はこの機会に導入を検討してみてはいかがでしょうか?

セレクトボックスのoptionを書き換えるjQueryプラグイン

javascript jQuery

こんにちは、こんばんは、新人の真崎です。 アドベントカレンダーを始めたはいいものの12/1が終わるまで時間がないので、簡単なネタで行きたいと思います。

セレクトボックスの内容を動的に書き換えたいことが、よくあるのですが、そんなときに使えるjQueryプラグインを書いてみました。 数十行なので読んでいただいたら、わかると思いますが、すこし説明します。

使い方

こんな感じに、hashの配列を渡してあげると、指定したセレクトボックスのoptionを書き換えてくれます。

var a = [
    { text: "a", value: "1"},
    { text: "b", value: "2", "data-b-c": "b"},
    { text: "c", value: "3", selected: true}
];
$("select").simpleOptions(a);

書き換えてくれる属性は、今のところ以下のものになります。

  • text
  • value
  • selected
  • disabled
  • data-*

他の属性も書き換えたいときは、適宜コードに追加してくだい。

セレクトボックスのvalueが変わったら、changeイベントを発火するようにしてあります。

コード

2番目のスクリプトタグ内のコードをコピペしてお試しください。

<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<script type="text/javascript">
(function($) {
    var simpleOptions = function(arr) {
        var $options = this.find("option");
        var selected = this.val();
        var diff = arr.length - $options.length;

        if (diff < 0) $options.slice(diff).remove();
        else if (diff > 0) {
            var fragment = document.createDocumentFragment();
            for (var i = diff; i; --i)
                fragment.appendChild(document.createElement("option"));
            this.append(fragment);
        }
        var some = arr.some(function(v) { return !!v.selected;});
        this.find("option").each(function(i, v) {
            v.value = arr[i].value;
            v.text = arr[i].text;
            v.selected = some ? !!arr[i].selected : ""+arr[i].value === selected;
            v.disabled = !!arr[i].disabled;
            for (var k in v.dataset)
                delete v.dataset[k];
            for (var k in arr[i])
                if (/^data-.+/.test(k))
                    v.setAttribute(k, arr[i][k]);
        });
        if (this.val() !== selected) this.change();
        return this;
    };

    $.fn.simpleOptions = simpleOptions;
})(jQuery);
</script>

<script type="text/javascript">
$(function() {
    $("select").on("change", function() {console.log(this);});
    var a = [
        { text: "a", value: "1"},
        { text: "b", value: "2", "data-b-c": "b"},
        { text: "c", value: "3", selected: true}
    ];
    $("select").simpleOptions(a);
});
</script>
</head>

<body>
    <select style="width: 100px">
        <option data-test="test"></option>
        <option data-test="test"></option>
        <option data-test="test"></option>
        <option data-test="test"></option>
    </select>
</body>
</html>

注意

DOMを使いまわしてるので、option自体に何かイベントを割り当てたときは、正しく動作しないので、ご注意ください。

まとめ

セレクトボックスのoptionを書き換えてくれるjQueryプラグインを作りました。 やっつけ感はありますが、大抵の場合はこれで事足りると思います。(アドバイスがあればお願いします)

GSOLエンジニアblog はじめました。

はじめまして、GSOLエンジニアblogの運用を任された真崎です。

この度、遅ればせながら、グローバル・ソリューションズにおいてもエンジニアblogを開設することとなりました。このblogでは、弊社エンジニアが、開発時のTipsやノウハウ、興味ある技術、弊社の製品の紹介などを書いていく予定です。

このblogをきっかけに、弊社のことにご興味をもっていただけたら幸いです。
よろしくお願いします。


12月といえば技術系blogでは、アドベントカレンダーの季節ですね。弊社(むしろ私個人)としてもこの流れに乗っておきたいなと思い、1エントリ目の記事からアドベントカレンダーの記事としていと思います。
それでは、はじめます。

サンプルエントリ

段落

あのイーハトヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモーリオ市、郊外のぎらぎら光る草の波。

あのイーハトヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモーリオ市、郊外のぎらぎら光る草の波。

フォトライフ

あのイーハトヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモーリオ市、郊外のぎらぎら光る草の波。


あのイーハトヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモーリオ市、郊外のぎらぎら光る草の波。


ブロック

あのイーハトヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモーリオ市、郊外のぎらぎら光る草の波。

大きい画像

あのイーハトヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモーリオ市、郊外のぎらぎら光る草の波。

h1見出し

あのイーハトヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモーリオ市、郊外のぎらぎら光る草の波。
ABCDEFGHIJKLMabcdefghijklm1234567890

h2見出し

あのイーハトヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモーリオ市、郊外のぎらぎら光る草の波。
ABCDEFGHIJKLMabcdefghijklm1234567890

h3見出し(*)

あのイーハトヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモーリオ市、郊外のぎらぎら光る草の波。
ABCDEFGHIJKLMabcdefghijklm1234567890

h4見出し(**)

あのイーハトヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモーリオ市、郊外のぎらぎら光る草の波。
ABCDEFGHIJKLMabcdefghijklm1234567890

h5見出し(***)

あのイーハトヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモーリオ市、郊外のぎらぎら光る草の波。
ABCDEFGHIJKLMabcdefghijklm1234567890

h6見出し

あのイーハトヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモーリオ市、郊外のぎらぎら光る草の波。
ABCDEFGHIJKLMabcdefghijklm1234567890

asin

あのイーハトヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモーリオ市、郊外のぎらぎら光る草の波。

「へんな会社」のつくり方 (NT2X)

「へんな会社」のつくり方 (NT2X)

あのイーハトヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモーリオ市、郊外のぎらぎら光る草の波。

リスト(ul,ol,dl)

あのイーハトヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモーリオ市、郊外のぎらぎら光る草の波。

あのイーハトヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモーリオ市、郊外のぎらぎら光る草の波。

  1. 大賞1名:Amazonギフト券5万円分
  2. 入選9名:Amazonギフト券1万円分
    1. 大賞1名:Amazonギフト券5万円分
    2. 入選9名:Amazonギフト券1万円分

あのイーハトヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモーリオ市、郊外のぎらぎら光る草の波。

大賞1名
Amazonギフト券5万円分
入選9名
Amazonギフト券1万円分

テーブル

あのイーハトヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモーリオ市、郊外のぎらぎら光る草の波。

名前 個数
りんご 1
みかん だいだい 2

あのイーハトヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモーリオ市、郊外のぎらぎら光る草の波。

PRE

.XXX {
  width:999px;
  height:999px;
}

.propA, .propB, .propC {
  width:999px;
  height:999px;
}

#YYY {
  width:9px;
  height:999px;
}