jQueryプラグインでシンプルなカウントダウンタイマーを作った
https://github.com/ninoseki/jquery-countdown
jQueryプラグインとしてシンプルなカウントダウンタイマーを作った。
localStorageに終了時刻を記憶しおいて、ウインドウ/ブラウザが閉じられた後でもカウントダウンが終わったかどうか判定できるってのが他との差別点。
jsdo.itにデモを挙げてみたんで、気になった方は見てみてください。
http://jsdo.it/ninoseki/qE64
By the power of Grayskull!
Chrmome extension版のTweetDeckを日常的に使っている。
あのLanuncherアイコンを押すと本体が新しいタブで立ち上がるって処理はどうやってるんだろう、と疑問に思ってソースコード見てみたら笑ってしまった。コメントが面白い。
function launchApp(app) { if (app.enabled) { chrome.tabs.create({ url : app.appLaunchUrl}); return; } else { // "By the power of Grayskull! Give me apps beyond apps!" chrome.management.setEnabled(app.id, true, function () { chrome.tabs.create({ url : app.appLaunchUrl}); }); } }
本体がdisabledになっている場合、無理やりenabledに変更してアプリを立ち上げてるのな。
うーん謎仕様。
ローカルで動くシンプルなWikiを作った
Wiki on hand
https://github.com/ninoseki/wiki-on-hand
便利機能満載のライブラリUnderscore.js
JavascriptライブラリUnderscore.jsがすごい便利。
すごい便利なのにもかかわらず、あんまり日本語の情報がなかったので、公式のドキュメントをスピリチュアル抄訳してみた。
http://documentcloud.github.com/underscore/
Collection Functions
each
_.each(list, iterator, [context])
listの要素をイテレートする。すべての要素はiterator関数にyieldされる。iteratorには(element, index, list)の3つの引数が渡される。もしlistがJavascript Objectだった場合は(value, key, list)になる。
_.each([1, 2, 3], function(num){ alert(num); }); => alerts each number in turn... _.each({one : 1, two : 2, three : 3}, function(num, key){ alert(num); }); => alerts each number in turn...
map
_.map(list, iterator, [context])
listのすべての要素を操作関数(iterator)でマッピングし、新しい配列を作る。もしlistがJavascript Objectだった場合、iteratorへの引数は(value, key, list)になる。
_.map([1, 2, 3], function(num){ return num * 3; }); => [3, 6, 9] _.map({one : 1, two : 2, three : 3}, function(num, key){ return num * 3; }); => [3, 6, 9]
reduce
_.reduce(list, iterator, memo, [context])
listの要素を1つの値に集約する。memoが初期値。iteratorはステップごとに値を返さなければいけない。
var sum = _.reduce([1, 2, 3], function(memo, num){ return memo + num; }, 0); => 6
reduceRight
_.reduceRight(list, iterator, memo, [context])
右方向からのreduce。
var list = [[0, 1], [2, 3], [4, 5]]; var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []); => [4, 5, 2, 3, 0, 1]
detect
_.detect(list, iterator, [context])
リストの要素の中から、一番最初に真値テスト(iterator)を通過したものを返す。
var even = _.detect([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); => 2
select
_.select(list, iterator, [context])
リストの要素の中から、真値テスト(iterator)を通過したものを返す。
var evens = _.select([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); => [2, 4, 6]
reject
_.reject(list, iterator, [context])
リストの要素の中から、真値テスト(iterator)を通過しなかったものを返す。
selectの反対。
var odds = _.reject([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); => [1, 3, 5]
all
_.all(list, [iterator], [context])
リストの要素がすべて真値テスト(iterator)を通過した場合、trueを返す。そうでない場合はfalseを返す。
iteratorが与えられなかった場合、代わりに真理値が使用される。
_.all([true, 1, null, 'yes']); => false
any
_.any(list, [iterator], [context])
listの要素が1つでも真値テストを通過した場合、trueを返す。そうでない場合はfalseを返す。
_.any([null, 0, 'yes', false]); => true
include
_.include(list, value)
valueがlistに含まれている場合、trueを返す。そうでない場合はfalseを返す。値の比較は===演算子で行われる。
_.include([1, 2, 3], 3); => true
invoke
_.invoke(list, methodName, [*arguments])
listの各要素に対してmethodNameで指定した関数を実行する。*argumentsは、指定された関数に引き渡される。
_.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); => [[1, 5, 7], [1, 2, 3]]
pluck
_.pluck(list, propertyName)
mapの便利バージョン。指定したプロパティ名に対応する値を集める。
var stooges = [{name : 'moe', age : 40}, {name : 'larry', age : 50}, {name : 'curly', age : 60}]; _.pluck(stooges, 'name'); => ["moe", "larry", "curly"]
max
_.max(list, [iterator], [context])
listの中の最大値を求める。iteratorが渡された場合、iteratorの返り値がランク付けの基準として使用される。
var stooges = [{name : 'moe', age : 40}, {name : 'larry', age : 50}, {name : 'curly', age : 60}]; _.max(stooges, function(stooge){ return stooge.age; }); => {name : 'curly', age : 60};
min
_.min(list, [iterator], [context])
listの中の最小値を求める。iteratorが渡された場合、iteratorの返り値がランク付けの基準として使用される。
var numbers = [10, 5, 100, 2, 1000]; _.min(numbers); => 2
sortBy
_.sortBy(list, iterator, [context])
各要素をiteratorの返り値でランク付けし、それと元にソートされたlistを返す。
_.sortBy([1, 2, 3, 4, 5, 6], function(num){ return Math.sin(num); }); => [5, 4, 6, 3, 1, 2]
sortedIndex
_.sortedIndex(list, value, [iterator])
二分探索で、valueがlistの挿入されるべき位置を調べ、それを返す。iteratorが渡された場合、iteratorの返り値がランク付けの基準として使用される。
_.sortedIndex([10, 20, 30, 40, 50], 35); => 3
toArray
_.toArray(list)
list(イテレートできるものならなんでも)をArrayに変換する。引数を変形するのに便利。
(function(){ return _.toArray(arguments).slice(0); })(1, 2, 3); => [1, 2, 3]
size
_.size(list)
listに含まれている要素の数を返す。
_.size({one : 1, two : 2, three : 3}); => 3
Arrays
first
first_.first(array, [n])
配列の一番目の要素を返す。nを指定しすると、先頭からn番目の要素までの配列を返す。
_.first([5, 4, 3, 2, 1]); => 5
rest
rest_.rest(array, [index])
先頭の要素を取り除いた配列を返す。indexを指定すると、index番目以降の要素を配列として返す。
_.rest([5, 4, 3, 2, 1]); => [4, 3, 2, 1]
last
_.last(array)
配列の最後にある要素を返す。
_.last([5, 4, 3, 2, 1]); => 1
compact
_.compact(array)
曖昧な値であるfalse, null, 0, "", undefinedを取り除いた配列を返す。非破壊的。
_.compact([0, 1, false, 2, '', 3]); => [1, 2, 3]
flatten
_.flatten(array)
多次元配列を一次元化する。非破壊的。
_.flatten([1, [2], [3, [[[4]]]]]); => [1, 2, 3, 4];
_.without([1, 2, 1, 0, 3, 1, 4], 0, 1); => [2, 3, 4]
uniq
_.uniq(array, [isSorted])
配列から重複を取り除く。===演算子で比較される。配列がソートされている場合は、isSrotedをtrueにすると処理が早くなる。非破壊的。
_.uniq([1, 2, 1, 3, 1, 4]); => [1, 2, 3, 4]
intersect
_.intersect(*arrays)
複数の配列の共通集合を返す。
_.intersect([1, 2, 3], [101, 2, 1, 10], [2, 1]); => [1, 2]
zip
_.zip(*arrays)
複数の配列の、同じ位置にある要素をマージする。
_.zip(['moe', 'larry', 'curly'], [30, 40, 50], [true, false, false]); => [["moe", 30, true], ["larry", 40, false], ["curly", 50, false]]
indexOf
_.indexOf(array, value, [isSorted])
配列にvalueが含まれていた場合、valueが一番最初に現れた位置を返す。含まれていなかった場合は-1を返す。配列がソートされている場合は、isSrotedをtrueにすると処理が早くなる。
_.indexOf([1, 2, 3], 2); => 1
lastIndexOf
_.lastIndexOf(array, value)
配列にvalueが含まれていた場合、valueが一番最後に現れた位置を返す。含まれていなかった場合は-1を返す。
_.lastIndexOf([1, 2, 3, 1, 2, 3], 2); => 4
range
_.range([start], stop, [step])
startからstopまでstepずつ増加(または減少)する整数のリストを作る。排他的。
startのデフォルト値は0。stepのデフォルト値は1。
_.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); => []
Function (uh, ahem) Functions
bind
_.bind(function, object, [*arguments])
オブジェクトを関数にバインドする。関数が呼ばれたとき、thisがobjectの値をとるということ。カリー化。
var func = function(greeting){ return greeting + ': ' + this.name }; func = _.bind(func, {name : 'moe'}, 'hi'); func(); => 'hi: moe'
bindAll
_.bindAll(object, [*methodNames])
複数の関数をオブジェクトにバインドする。イベントハンドラーに関数をバインドするときに便利。
var buttonView = { label : 'underscore', onClick : function(){ alert('clicked: ' + this.label); }, onHover : function(){ console.log('hovering: ' + this.label); } }; _.bindAll(buttonView); jQuery('#underscore_button').bind('click', buttonView.onClick); => When the button is clicked, this.label will have the correct value...
memoize
_.memoize(function, [hashFunction])
関数の計算結果をキャッシュする。メモ化。hasFunctionが指定された場合、結果をストアするためのハッシュキーとして利用される。hasFunctionのデフォルト値は一番最初の引数。
var fibonacci = function(n) { return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2); }; var fastFibonacci = _.memoize(fibonacci);
delay
_.delay(function, wait, [*arguments])
setTimeoutのように、ミリ秒後に関数を呼び出す。argumentsを指定した場合、それが呼び出される関数に引き渡される。
var log = _.bind(console.log, console); _.delay(log, 1000, 'logged later'); => 'logged later' // Appears after one second.
defer
_.defer(function)
コールスタックが空になるまで、関数の呼び出しを遅延させる。delay = 0でsetTimeoutを使う場合と同じ。複雑な計算を行ったり、UIスレッドをブロックせずにまとまったHTMLレンダリングを行いたいときに便利。
_.defer(function(){ alert('deferred'); }); // Returns from the function before the alert runs.
throttle
_.throttle(function, wait)
スロットル化された関数を返す。ラップされた関数はwaitミリ秒に多くても一度しか実行されない。レートが制限されたイベントを起こすのに便利。
var throttled = _.throttle(updatePosition, 100); $(window).scroll(throttled);
debounce
_.debounce(function, wait)
関数が実行されてからwaitミリ秒が経過するまで、繰り返しの呼び出しを抑止する。何らかの入力がストップしたときに実行される振る舞いを実装したいときに便利。
var lazyLayout = _.debounce(calculateLayout, 300); $(window).resize(lazyLayout);
once
_.once(function)
一度しか実行されない関数を作成する。修正された関数の二度目以降の呼び出しは、なんの影響も与えず、最初に呼び出されたときの返り値を返す。初期化処理に便利。
var initialize = _.once(createApplication); initialize(); initialize(); // Application is only created once.
wrap
_.wrap(function, wrapper)
最初の引数で指定した関数をwrapper関数の中にラップする。wrapper関数には指定された関数の実行の前後で行われる処理を記述することができる。
var hello = function(name) { return "hello: " + name; }; hello = _.wrap(hello, function(func) { return "before, " + func("moe") + ", after"; }); hello(); => 'before, hello: moe, after'
compose
_.compose(*functions)
複数の関数の合成関数を返す。関数は次の関数の返り値を引数としてとる。関数f(), g(), h()を合成しすると関数f(g(h()))ができる。
var greet = function(name){ return "hi: " + name; }; var exclaim = function(statement){ return statement + "!"; }; var welcome = _.compose(exclaim, greet); welcome('moe'); => 'hi: moe!'
Object function
keys
_.keys(object)
objectのプロパティ名をすべて取り出す。
_.keys({one : 1, two : 2, three : 3}); => ["one", "two", "three"]
values
_.values(object)
objectのプロパティ値をすべて取り出す。
_.values({one : 1, two : 2, three : 3}); => [1, 2, 3]
functions
_.functions(object)
objectが持つすべての関数プロパティ名をソートして返す。
_.functions(_); => ["all", "any", "bind", "bindAll", "clone", "compact", "compose" ...
extend
_.extend(destination, *sources)
soucesオブジェクトのすべてのプロパティをdestinationオブジェクトにコピーする。sourcesの中に同じ名前のプロパティが含まれていた場合、より後のもので上書きされる。
_.extend({name : 'moe'}, {age : 50}); => {name : 'moe', age : 50}
defaults
_.defaults(object, *defaults)
objectがdefaultsオブジェクトのプロパティを持っていない場合、objectにそのdefaultsオブジェクトのプロパティを付与する。
var iceCream = {flavor : "chocolate"}; _.defaults(iceCream, {flavor : "vanilla", sprinkles : "lots"}); => {flavor : "chocolate", sprinkles : "lots"}
clone
_.clone(object)
objectのシャローコピーうを作る。ネストされたオブジェクトや配列は、参照コピーされる。
_.clone({name : 'moe'}); => {name : 'moe'};
力尽きた。残りもそのうち。
ローカルでデータを管理するポスト・イット的なアプリつくった
PostIt!
retrospctiveapp(https://github.com/paulbjensen/retrospectiveapp)をforkして、データをローカルに保存するようにした。
あとデザイン周りも多少いじってる。
よそにデータを送信したりしないので、私的なメモとして使えるんじゃないかな。
コードはこちらから https://github.com/ninoseki/retrospectiveapp