FC2ブログ
七つの海のときどき航海日誌
七海生産者商会の会長が徒然と書き留めてみた大航海時代の由無しごと。
えーっといきなりのマイナーバージョンアップです
世界周航図をv3.1にアップデートしました~。
変わったところ。

「超軽くなった?!」

見た目はほとんどかわってませんけど、中身はぱわああーっぷ!

うち自身の使い方は、DOLをウィンドウ表示して裏っ側にこの地図をおいといて、
必要になったらその場で使う~といった感じなのですが。
これまでのバージョンだと、地図の上でマウスをぐるぐる動かすだけで、
アラ不思議!DOLの画面がカクカクに!
なんてことになってたのでした‥
それもそのはず、地図の上でマウスを動かすだけで、CPUの使用率が100%まで跳ね上がってたんですから‥

これをなんとかしたいなーと色々試してみてたんですけど、これがなかなか難しくて‥
地図は出来上がってたので、高速化は後回しにしてリリースしちゃった次第なのでした。
それから4日。ちょっと手間暇かかっちゃいましたが、
なんとか出来上がったので間髪入れずリリースしちゃいまーす

結構(そうとう?)軽くなったと思うので、是非一度おためしくらさーい

世界周航図は七海のトップページからどーぞ♪

ここからは技術めも
こっからは自分φ(,_, )メモも含めてちょっと技術的なお話
やったこと
Javascriptでのイベントのリスナの置き方を変えてみました。

これまでは、地図上の全部のイベントをその場で拾って、
イベントを拾うごとに、都市の上かどうかの判断を、
都市のデータが入った配列をぐるぐる回しながら行ってました。
そう。マウスが1px動くたびにです!
Javascriptは単一スレッドでしか動作しない言語なので、
まうすをぐーるぐるなんて動かすとそれこそもう大変。
ジョブは全部キューにたまっていって、これをこなすだけでCPUはおおわらわ
そりゃあCPU占有しちゃいますよ‥と。

そこでちょっと古い手?ですけど、イメージマップを使って、
必要な箇所にだけイベントリスナを配置することにしました。
ただし、わざわざべた書きのイメージマップは使いたくないです
そりゃべた書きだと楽ですけど、後々のメンテナンスがたーいへん!
いちばん初期の頃の地図は、べた書きのイメージマップを使ってたんですけどねぇ。
そこで、イメージマップの中身をJavascript内で動的に生成しちゃおうかなーと。

DOMを使うと、Javascript上からHTML内の全てのオブジェクトを操作できるんです。
これを使って、HTMLに書いた次のタグの隙間にエリア指定のタグを挟み込んでいきます。
<map name="navigator_map" id="event_listener_map">ココ</map>
もちろん、最初はなーんにも書いてないんですよ?

で、タグを挟み込むだけなら楽チンなんですけど、
ただ埋め込むだけだとホントの「文字列」としてしか認識してくれないのです。
やりたいのは、埋め込んだタグに「onmousuover」や「onmousedown」などの
イベントを仕込んでしまうこと。
じつはこの辺は、街や郊外の地図のポップアップですでに実装してあるんですが。
オブジェクトのイベントに関数をバインドしているっていうイメージになるのかな?
こんな書き方。
tagObj.onclick= function() { originalFunction(value1,value2); };
サンプルはこちら。test1.html
(追記:この手法を「クロージャー」というみたいです。 すなわち、
「関数内で宣言した無名関数とローカル変数をカプセル化して利用する技術」ですって)

ただ、この関数の中のvalueがforループの中での変数のばあいは、
このままバインドしても上手く出来ません。
実際にイベントが発生し、関数を評価するときに変数の値を取得しようとするからです。
もちろんそのときはforループが終わったあとなので、変数の中身は思い通りにならず‥
サンプルはこちら。test2.html
要はオブジェクトのスコープが非常にあいまいなんですねえ。
(無いと言っても過言じゃないかも)

Javascript1.7以降ではlet文というのが追加されてるそうですが、
現行のIE6と7はJavascript1.3までしか対応してません。
(参考:JavaScriptのバージョンについて調査)
そこで色々調べてみると‥‥
「with」文と「オブジェクトリテラル」を使った書き方があることが判明
(参考:JavaScriptでブロックスコープを実現する)
forループの中でこれを使ってスコープを限定して記述しなおしたサンプルがこれ。
test3.html
ちゃんと思惑通りに動いちゃいましたあ~

で、要はこれを使って、面倒なエリア指定タグを動的に書いちゃいましたよというお話。
イメージマップを使うことで、必要な箇所以外ではイベントをハンドルしなくなって、
もうそれはそれは、250%(当社比(?))くらい軽くなってるます。
スッキリスッキリ


▲閉じちゃう▲