‘プログラム’ カテゴリーのアーカイブ

toastrを使ってみた

 プログラム
 公開日:2016年5月8日

 先日、
これこれに書いたように、
Geolocationが許可されない場合に、
freeGeoIPで代用したことを示すために
あえてアラート表示は残したのですが、
Chromeだと毎回出るのがちょっとウザイ。

 window.alert を使うとエラー表示がお手軽にやれるのですが、
モーダルなダイアログになっているので、
ボタンを押さないと先へ進まない。

 言わば、
進行がブロックされる通知表示なわけで、
ブロックされない通知表示なら
スマートな感じになるんじゃないかな、
と思って探してみたら、
こちらのtoastrというのを見つけました。

 こちらの動作デモを試してみると、
スタイリッシュでなかなか良さげな感じです。

 ちなみに、
こういうのをトースト表示と言うらしい。
両面焼いた食パンをトーストと言いますが、
なんか関係があるのでしょうか(^_^;)

 使い方はしごく簡単。
cssとjsを読み込んで、

toastr.error('message');

とか書くだけ。
cssとjsについてはCDN版もあるので、
ファイルを自分のサーバーに置かなくても行けますね。
ただ、
jQueryに依存しているので、
あらかじめ読んでおく必要があります。

 オプションも豊富です。
こちらの動作デモで確認できます。
timeout で自動消去される時間を設定しますが、
トースト表示中にマウスカーソルをhoverさせると、
消去されずに表示され続けるようになっています。
timeoutしても表示されたままになりますが、
hoverを解除すると自動消去されます。
その時間は Extended time out で設定するようです。

 v2.1.2における、
オプションのデフォルト値は以下のようになってました。

 また、
こちらにあるようにCSSで上書きすれば、
アイコンを好きなようにカスタマイズできるようです。
iconClass オプションをいじっても同様にやれそうな感じっぽい。

JavaScriptのビット演算な罠

 プログラム
 公開日:2016年1月22日

 先日、
国コードから割り当て済みIPv4を抽出、あるいはその逆を行う
といった感じのアプリというかツールっぽいのを作ったのですが、
その際にビット演算でちょっとハマったので、
書いてみたいと思います。

 こちらにあるように、
JavaScriptでビット演算を行うと数値は32ビットな値として扱われます。

 あらためて確認すると、
32ビットというのは0または1の2進数なビットが32個連なったもので、
2の32乗個、すなわち4294967296個の組み合わせが表現できます。
10進数の正の整数として表現すれば、
0~4294967295の最大10ケタとなります。
また16進数な表記では、0x0~0xffffffffの最大8ケタとなります。

 ところでJavaScriptにおける数値は、
64ビット倍精度浮動小数点数の形式である
IEEE754にしたがって実装されています。
仮数部の精度としては53ビットありますので、
10進数の正の整数としては最大16ケタまで表現できることになります。

 ということで実際に確認してみます。
意図的に選んだ16進数表記な数値を console.log()してみました。
以下のように、期待した通りの結果となっています。

 次にビット演算をやってみます。
変化が起きないようにゼロとビット論理和してみました。
以下のような結果となりました!

 興味深い結果となってますが、
仕様通りに32ビットに収まる値となっています。
32ビットを超える部分はカットされ、2の補数な表現となっています。
つまり符号あり32ビットな整数として扱われています。
値としては、-2147483648~2147483647を表現できることになります。

 で、ここから私がハマった話に入ります(^_^;)
IPv4では表現できるアドレス範囲は、
0.0.0.0~255.255.255.255となっています。
16進数で表記すれば0x00000000~0xffffffffとなり、
ちょうど32ビットに収まります。
ソートする必要があったので、
文字列表記なアドレスを全て数値に変換して格納するようにしました。
127.255.255.255までは問題ないのですが、
128.0.0.0以降になるとソートが期待した通りにならなくなります。
自分の中では符号なし32ビットだったのですが、
実際は符号あり32ビットなんです(^_^;)
ビット演算すると32ビット数値として扱われることは知っていたのですが、
符号までは意識していませんでした。
というか
32ビットぶんを目一杯使うことってあまり無いし・・・。
ビットなフラグ用途なことが多いし・・・。

 愚痴っていてもしょうがありません(^_^;)
1)ビット演算を使わずに変換する
2)負数になったら正規化する
のどちらかにすれば解決するはずですが、
なんかもっとスマートな方法はないかと調べてみたら、
これを見つけました。
こんな手があったのね!

 ときに、
JavaScriptのビットな右シフトには、
>>>>> があります。
2つあることをすっかり忘れてました(^_^;)
前者は算術右シフト、後者は論理右シフトです。
左シフトは結果が同じなので区別してないだけです。
端的に言うと、
符号あり数値として扱っているなら算術右シフトを、
符号なし数値として扱っているなら論理右シフトを
使うことになります。

 重要なことは >>> すると、
数値は符号なし32ビットな値として扱われます。
符号あり32ビットを符号なしに変換できることになります。
実際にやってみると以下のようになります!

 JavaScriptに型宣言はありませんが、
number | 0 とか number >>> 0とか書けば、
符号あり32ビット値や符号なし32ビット値を暗黙的に示すことができます。
浮動小数点数から32ビットな整数へ変換するのにも利用できます。
JavaScriptエンジンに対して最適化を促すことができるのかも。
asm.jsな技術とかはこういったのを利用して下位互換性を図っているようです。

Mithril.jsを使ってみた(2)

 プログラム
 公開日:2016年1月15日 / 更新日:2016年2月1日

 今回は、
前回ではまだ使っていなかった、
m.requestm.routeなどのAPIを使って
ちょっとしたアプリを作ってみました。
APIについては個人的に注意すべき点などを感じたので、
それについて書いてみたいと思います。

  m.requestを使うと非同期処理を簡便に書くことができます。
こちらにあるように、
完了時コールバックをPromise風に記述することになるので、
処理の流れも分かりやすくなります。

 ただ、 m.request(param)では
JSONやJSONPでの通信を前提としているような所があるので、
生のデータとして受け取るには以下のように
param.deserializeを設定する必要があります。

Mithril.jsの内部的には
XMLHttpRequest(xhr) の responseTextを返しているようなので、
基本的にはバイナリとか扱えない感じ。

とかやれば、バイナリ文字列という形で受け取れる
少々トリッキーだし余計な処理も必要となる。

 ということで、バイナリ(arraybuffer)とかで受け取る場合は、
直接、 XMLHttpRequestを使って自前で書いた方が早いかも。
responseTypeを指定して responseで受けとる方が、
個人的には直感的で分かりやすい気がする。
というか、 m.requestのパラメータで
responseTypeを指定できるようにすれば良いのに、と思う。
(古いブラウザへの配慮なのかもしれないけど・・・)
param.configを使うと、以下のように
xhrを置き換えて好きなようにやれるようなのですが、
なんだかなぁ~、という感じになります(^_^;)

 また、 m.requestのパラメータは色々あって、
使い所がよく分からなかったりするので、
m.requestを使わずにxhrでやった方が分かりやすいこともあるかもしれない。
Mithril.jsの流儀に従うには(というか描画を遅延させるには)、
m.startComputation()m.endComputation()を噛ますだけで済むので、
大して手間も掛からなさそうだし。
例えば以下の様な感じかな。

 次に、
m.routeこんな感じのAPIです。
複数のComponentを一意に m.mountできるAPIといった所でしょうか。
いわゆるSPA(Single Page Application)を作るための仕組みだそうです。
SPAというのは、
URLは同じだけど(クエリとかハッシュとかつく場合あり)、
複数のページから成っているかのように振る舞うアプリといった感じかな。

 注意点としては m.routeによってページが切り替わるたびに、
Controllerのコンストラクタがnewされるようなので、
切り替わっても初期化されないようにするためには、
ちょっと工夫が必要です。
以下のように書くと切り替え毎にpropが初期化されてしまうので、

以下のように書く必要があります。

newの戻り値はインスタンスとして扱われるので、
上のように書いても問題無いです。

 なお、 m.routeを使うと
デフォルトではURLにクエリ文字列が付きます。
例えば http://foo/bar/index.html?page1 とか。
m.route.modeを設定するとハッシュとかに変更できます。
例えば http://foo/bar/index.html#page1 とかになります。
ハッシュにすると名前付きアンカーが使えなくなりますが、
どのブラウザでもページリフレッシュが発生しないようにできるとのことです。

 今回作ったアプリでは、
<input type="text">な入力があります。
入力値を制限するために、
oninputなイベントを設定しているのですが、
Mithtil.jsでは入力する毎に、
インタラクティブに描画を更新できるようにできます。
これはこれで便利なわけですが、
入力後のOKボタンで確定させるような作りの場合は、
入力毎に再描画が発生するのはムダになります。
m.redraw.strategy('none')とやれば
次回の再描画をキャンセルすることができます。
ただし効果は1フレームだけなので注意が必要です。
その後に m.redraw.strategy('diff')に自動で再設定されます。

 それから、
Mithril.jsではインジェクションな攻撃とかを防ぐために、
テキストは document.createTextNode()によってエスケープされます。
そのため例えば '&nbsp;' と書いても、
「改行しない空白」には成らずに、「&nbsp;」と単なる文字と成ります。
そのため期待した通りにするには、
m.trust('&nbsp;')と書く必要があります。

 んで、作ったアプリというのは
国コードから割り当て済みIPv4を抽出、あるいはその逆を行うというもの。
データはこちらを参照させていただいております。
1日に1回程度更新されているそうなので、
1日分はキャッシュするようにしました。
毎回アクセスするのはサーバーに負荷を掛けることになると思うので。

 それにしても、ここを見ると
人口の割にアメリカは確保しすぎだろ!
って、ツッコミたくなりますね(^_^;)

 ということで長々と書いてしましましたが、
アプリを試すにはこちらからどうぞ。

★2016年1月31日追記
IPアドレスから国コードを抽出した際の表示を変更してみました。

★2016年1月24日追記
国コードはドロップダウンなリストでも選べるようにしてみました。
また、割り当て済みの個数とかの表示を追加してみました。

Mithril.jsを使ってみた

 プログラム
 公開日:2015年11月1日 / 更新日:2016年3月5日

 Webアプリを作る際に、
フレームワークとか使うと、
労力の低減とか作業効率とかを期待できそうです。

 一方で、
それぞれの流儀に従った書き方をする必要が出てきます。
新たに学習したことが当面はムダにならないように、
フレームワークの選択は重要かもしれませんが、
好きなように色々試してみるのが良いのかも。

 こちらにあるように、
JavaScriptなMVCフレームワークはたくさんあります。
Angular.js や Vue.js とかが良さげかなと、
調べてみたことはありましたが、
実際に使ってみたことはなかったりします(^_^;)

 そんな折、
こちらこちらで書かれている Mithril.js に興味を持ちました。
軽量で高速というのに惹かれました。
APIの数が少なくて学習コスト低めなのも良さげです。
公式に準じた(?)日本語のページがあるのも嬉しいですね。
ちなみに、現状の最新バージョンは 0.2.0 です。

 ということで、こちらのページで学んでみました。
こちらは英語のページですが、より具体的で参考になるかも。
とりあえず大体理解しました。

 データ構造となるModelの各プロパティに、
m.prop() で生成した getter/setter をセットし、
それらをViewとなる仮想DOMの属性にも設定することで、
getter/setter 経由で同期するようにして、
双方向バインディングを実現しているようです。
また、 m.withAttr() を使うことで、
仮想DOMの属性に対するイベントハンドラを簡便に作れるようになってます。

 仮想DOMというのは、
実DOMを生成するための内部的なデータオブジェクトで、
それらの変更を監視して実DOMの生成や更新を行うことで、
必要最小限の描画コストになるようにする仕組みです。

 非同期処理など自動的に監視できないような場合は、
こちらにあるように対処する必要があるようです。
というか非同期処理が完了するまで描画を遅延させる仕組みと言えるかも。
プログレス表示とかしたい場合は明示的に m.redraw() すれば良さそうです。

 仮想DOMはMithril独特の書き方をする必要があります。
慣れればそれほど手間ではないように感じますが、
HTMLをMithrilな仮想DOMに変換するツールを使うと楽かも。
JSX形式で記述してMSXというコンパイラで変換するやり方もあるようです。

 そして、
m.mount() を使って、
ControllerとViewを実DOMに結びつけます。
あとはMithrilがうまいことやってくれます。
仮想DOMに設定したイベントハンドラが呼ばれると、
Modelも更新されるようにできるので、
Controllerでやるのは初期化くらいな感じですね。

 ということで、
実践的な学習も兼ねて、
ちょっとしたアプリっぽいのを作ってみました。
こちらの寸評に書いてある3つの確率を入力して、
運試しをするというアプリです(^_^;)
各ボックスには0~100の値しか入力できないようになってます。
横に並んだ3つの入力値の合計が100になると、
背景が淡いピンク色から淡い空色に変わります。
全ての背景を淡い空色にすると、
「運試し」ボタンが押せるようになります。
ボタンを押すたびに、
各面の確率が異なる3面サイコロを転がして結果を表示します。
試すにはこちらからどうぞ(^_^;)

★2016年3月5日追記
データ自動取得な機能を追加してみました(^_^;)

 実際に試してみると、双方向バインディングは便利ですね。
DOMにidやclassを振って選択するといった従来のやり方でも、
数が少なければそれほどの手間ではないかと思いますが、
数が多くなると双方向バインディングの方が楽チンです。

 使ったAPIは、
仮想DOMを記述するための m と、
m.prop, m.withAttr, m.mount の4つだけ。
これだけ覚えればなんとかなりそうな雰囲気です。
他にも、
m.request, m.route, m.componentなど
便利そうな機能があるようです。
Mithrilはなかなか良さげかも、

ES6のPromiseについて見てたら・・・

 プログラム
 公開日:2015年10月30日

 先日、
ES6について書いた派生で Promise を見てたら、
ちょっと気になることを発見しました。
というか、
そういえば意識したこと無かった、
という感じですが(^_^;)

 ときに、Promise というのは、
非同期処理を一意に扱えるようになるオブジェクトで、
ES6で導入される予定になっています。
ブラウザによっては既に使用可能になっているようです。

 Promise の学習を目的としたこちらのページを参照していた所、
「同期と非同期の混在の問題」というのに目が止まりました。
ざっくり言うと、
呼び出される順番が期待したようにならない場合があるので、
非同期コールバックを同期的に呼び出してはいけない

ということです。
内容を読んでみるとナルホド納得。
このことを意識せず非同期処理を書いていたので一つ勉強になりました。

 要するに、
完了が非同期になるものとして呼び出したのに、
即完了して同期呼び出しになる場合があるのは良くない
ということです。

 先のページから引用するとこんな感じ。
まず、好ましくない例。

そして、好ましい例。

違いは setTimeout を使っているかどうかです。
fn をそのまま呼ぶと同期になってしまうので、
非同期になるように setTimeout(fn, 0) するというわけですね。

 重要なのは、
Promise を使うと非同期で処理されることが保証されるので、
上記のような問題は起きないということです。
さらに、
コールバック地獄から開放されるという利点もあります(^_^;)
まぁ、これは書き方次第でどうにかなるようにも思いますが、
処理の流れがパット見で分かりやすくなるのは間違いなさそうです。

 そんなわけで、
非同期処理する際は積極的に Promise を使って行きたい所ですが、
現状ではまだ対応してないブラウザとかあるようなので、
注意しながら従来通りの書き方でやるか、
こちらに書いてあるようなライブラリを使うかのどちらかになりそうですね。