[JavaScript]iPhoneでも動くテキストエリアの履歴機能を作った

textareahistory-js
http://github.com/takimo/textareahistory-js

localStorageを使って指定した分の履歴を自動的に保存してくれるようになります

こんな風に書けばうごくはず

    <script src="../lib/namespace.js"></script>
    <script src="../src/textarea_history.js"></script>

    <textarea id="textareahistory"></textarea>
    <div class="diary" id="historycontroller"></div>
    <script> 
        Namespace.use('net.takimo.html.textarea_history TextareaHistory').apply(function(ns){
            var textareaHistory = new ns.TextareaHistory(document.querySelector('#historycontroller'),{
                textareaRef: '#textareahistory',
                delay: 1000,
                max: 3,
                loadButtonText: "読み込む"
            });
        });
    </script> 

動かすためには

namespace-jsが必要です。thx hirokidaichi!
http://github.com/hirokidaichi/namespace-js

prototype.jsで出来ることをover JavaScript1.6でやるには?

XMLHTTPRequestまわりはひとまず置いておく。
これどうすんだよっていうのがあったら教えてください。
今のところまったくHTML5は関係ない記事になっている。
メモメモ。

$

$$([CSS Selector]).first()

document.querySelector([CSS Selector])

var element = document.querySelector('input[name=id]');
console.log(element.value);
$$([CSS Selector])

document.querySelectorAll([CSS Selector])

var elements = document.querySelectorAll('li.userProfile');
console.log(elements);

$A

Array.prototype.slice.call(arrayLikeObject, 0);

var $A = function(arrayLikeObject){
    return Array.prototype.slice.call(arrayLikeObject, 0);
}
var elements = $A(document.querySelectorAll('li.userProfile'));

Array

each

Array.forEach();

var numbers = [1, 2, 3, 4, 5];
numbers.forEach(function(value){
    console.log(value);
});
// 1, 2, 3, 4, 5
inject

Array.reduce();


select(findAll)(ArrayではなくEnumerableですが

Array.filter();

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].filter(function(n) { return 0 == n % 2; })
// -> [2, 4, 6, 8, 10]

Element

toElement

だいぶ簡易、toElementの挙動は全部追ってないです(scriptタグのところとかとか)

var html = "<ul><li></li></ul>";
var tmpElement = document.createElement('div');
tmpElement.innerHTML = html;
var element = tmpElement.querySelector('*');
console.log(element);
addClassName, hasClassName, removeClassName

Element.classList

var element = querySelector('#popup');
element.classList.add('opened'); //addClassName
element.classList.contains('opened'); // hasClassName
element.classList.remove('opened'); // removeClassName

Event

observe

Element.addEventListener

var element = querySelector('input[type=submit]');
element.addEventListener('click', function(event){
    event.preventDefault();
    event.stopPropagation();
    console.log("イベントの伝搬を止めました");
});

iPadの持つ可能性

自分が考えているiPadアプリの可能性をアイデアとして書き連ねてみた。
ここで書いてもなんの成果にもならないけど、iPadがリリースされたら何かiPad用のアプリを出して検証してみたい。

自分が考えているiPadの持つ優位性

  • ネットにつながる紙やリモコンな感じで使える(使えそう
  • みんなで囲うことができる

ターゲット

とりあえず、子供がいる家族

イデア

  • テレビ

番組に向けて投稿とかができる。
Dボタンとかの延長みたいなイメージ。
みんなのコメントとかが見れるといいかも。

  • 料理

DSのソフトより分かりやすくレシピを表示したり、手で操作できるできるのでカウンターとかに起きながら料理をサポート。

  • 御買い物

チラシを見る感じでネットスーパーから購入できる。

  • 出前

みんなでどれにしよーとかあーだこーだ言いながら決められる。

  • ゲーム

例えば、ボードゲーム
http://d.hatena.ne.jp/mizzusano/20100202/1265072199

テーブルにおいてみんなで触ってゲームをできる。
家族で助け合って他の家と戦うとか楽しそう!
正真正銘のファミリーコンピューターが生まれるかも?

帰りの電車で思い浮かんだのはこんな感じ。
リビングPCとしていろんなものをインターネットに繋げていけると考えると、とてもわくわくしています。

PocketWiFiの速度を測ってみた

必要にかられ、PocketWiFiを契約しました。
どのくらいの性能なの?
使い勝手は?
というのがみんな気になるところだと思うのでまとめてみました。

速度計測結果

BNRスピードテストで計測してみた。
http://www.musen-lan.com/speed/

測定サイト: http://www.musen-lan.com/speed/ Ver3.5001
測定日時: 2010/01/30 22:59:52
回線/ISP/地域:

                                                                                                  • -

1.NTTPC(WebARENA)1: 886.889kbps(0.886Mbps) 109.92kB/sec
2.NTTPC(WebARENA)2: 932.718kbps(0.932Mbps) 116.49kB/sec
推定転送速度: 932.718kbps(0.932Mbps) 116.49kB/sec

まぁまぁってとこですかね?
普通にネットとかSSHしている分には全く問題ない感じかなと思いました。

言うだけは簡単なので釣りゲーを実際にやってみた

釣り☆スタ(GREE

  • 登録からチュートリアル
  • GREEへの登録必須
  • 釣り☆スタのトップには今何人参加しているか人数が右から左に流れている
  • 簡単なチュートリアルが表示されていて、早速釣ってみようとなる
  • Flash画面に遷移、釣りをする
  • まず、左右に落とす位置を決める矢印バーが動いているのでセンターキーを押して落とす横位置を決める
  • その後、上下に矢印バーが動き出すのでセンターキーを押して落とす縦位置を決める
  • 横位置と縦位置が決まったら画面右上に浮きの浮き沈みが分かるウィンドウが表示され、ユーザーは浮きがさがったらセンターキーを押して魚に食わせるということらしい
  • 魚がひっかかったら水中画面に遷移
  • 魚は画面を縦横無尽に動く
  • 水中画面には白い枠とその中に丸い円が描かれていて、引き上げるには中心に近い円上に魚がいるタイミングに合わせてセンターキーを押して引き上げていく
  • 何回か上記のアクションを繰り返すとつり上げられる
  • つり上げられるとFlash画面から通常のサイトに戻り、何の魚をつり上げられたか確認できる
  • つり上げられた魚は魚図鑑というところに記録される
  • 釣り☆スタサークルへの参加をアドバイスされる
  • チュートリアルが終わると「川釣り」に行けるようになる
ゲームの進行と面白さ
  • いろんな魚を釣り上げることで称号を得ることが出来る
  • 同じ魚でもサイズが大きいのをつり上げても称号をあげることが出来る
  • つり上げた魚によって★が違い、魚ごとにもらえる★の数が違う&大きさによっても数が違う
  • ★が一定数集まったら称号があがる仕組みらしい(http://daisuki.in/~game/modules/pico/index.php?content_id=23
  • 称号があがらないと新しい釣り場所に行けない(新しい魚を釣れない)
  • さらに、各釣り場所にはランキング機能があって大きい魚を釣り上げられるとランキングに載ることが出来る
課金のうまさ
  • 称号をあげる近道として「シカケをかって魚のサイズUPを狙うのが一番の近道」とヘルプに書いてある
  • また、エサがいい物だと大物がかかる。だが、おおものをつり上げるためにはより強力なサオを購入する必要がある
  • 各アイテムは消費されるもの(エサは個数、サオやシカケは壊れる)
  • シカケ、竿やエサはゴールド(GREE有料コース登録【月額or都度課金】へのおまけ、スポンサーサイトに登録する、GREEアバターのアイテムを購入するオマケ)か、ポイント(GREE内でたまるポイント、ゲームとかでたまるらしい)で購入できる
無料でやり続けたいユーザーの存在
  • ゲームでポイントがたまるので、機械のごとくポイント稼ぎ(RPGのレベル上げみたいな感じですね…)

(ここでかなりのPVを生み出している気がする、違うのかな)

備考
  • 釣り☆スタサークル(GREE公認)というのがあって、その参加員数は34万人ほど(09/09/27時点)
  • トピックはGREEによって管理されている(トピック作成要望トピックで申請する)
  • トピックは攻略トピックがメインで釣り場所ごとの攻略トピックがたくさんある

釣りゲータウン2(モバゲー)

ゲームの進行とシステム
  • ほぼ同じ
  • つり上げる仕組みで円の中に押したらつり上げゲージが下がる部分がある(ここは違う?)
  • つり上げる仕組みがGREEよりひねっている部分がある(円の真ん中に星マークや釣り針マークが表示されていて、それらが表示さているときに円の真ん中でキーを押すと確変モード(円の中ならどこを押してもつり上げゲージが上がる状態になる)や一本釣りモード(円が小さくなるが5秒以内に円の中でキーを押せれば一発でつり上げられる))
釣りゲータウン2のサークル
  • モバゲーが公式で運営
  • 参加人数は30000人ほど

総評

  • システムはたしかに似ている
  • でも、携帯の釣りゲームってこんな感じなシステムになるよなって印象(釣る場所を選択→釣りをする→釣り具を揃える)
  • つり上げるアクションはもうちょっと別な表現方法が出来なくもないかなって思った(川のぬし釣りみたいなつり上げる方法は使っちゃダメなんだろうなぁ、というか押しっぱなしという状態をFlashLiteが検知できないか
  • クオリティはGREEのほうがかなりいい気がするし、親切かな?
  • 参加している人口もGREEが圧勝(の予感)
  • GREEはゲームポータルって感じ、自分のホームに人気があるゲームへの導線がある(「釣りに行く」「ペットを飼う」「庭をつくる」「探検に行く」)
  • 一方モバゲーのホームはmixiみたいなメニューが並んでいるだけ(「日記を書く」「ミニメール」「サークル」「あしあと」…)、下の方にゲームへの導線はあるけど
  • GREEはゲーム作りうまいなぁ(課金を含めて)

AS3経験者がたぶんはまるであろうAS2の落とし穴のまとめ

自分がはまりまくっているのでそのまとめ。
他にもこれってのがあれば教えて頂けるとうれしいです。

getter,setter使える

AS3に近い感じでOOPを意識してクラス作れる

public function get hoge():String
{
    return this._hoge;
}
public function set hoge(hoge:String):Void
{
    this._hoge = hoge;
}

クラスの継承とオーバーライドをする事が出来る

ただし、装飾子はprivateとpublicのみ

class hoge
{
    private var _age:Number;

    public function hoge()
    {
    }

    public function talk(message:String):Void
    {
        trace(message);
    }

    private function set age(age:Number):Void
    {
        this._age = age;
    }
}

hogeを継承するクラスmoge

class moge extends hoge
{
    public function moge()
    {
        super.age = 18;
    }

    public function talk(message:String):Void
    {
        trace("moge : " + message);
    }
}

イベントを取得できるのは、ムービークリップ、ボタン、一部のコンポーネント

自分でディスパッチやろうと思えばできる。
ただし、リスナーに登録するときのインターフェースはすべてが同じではない

hoge_btn.onRelease = function():Void{
    trace("click hoge_btn!!");
}

リスナー関数のスコープがAS3と違う!

Delegate.createを使いましょう

trace(this); // _level_0
hoge_mc.onRelease = function():Void{
    trace(this); // hoge_mc
}

thisを迷子にさせないようにする

trace(this); // _level_0
hoge_mc.onRelease = Delegate.create(this, function():Void{
    trace(this); // _level_0
}

ムービークリップの深度管理

MovieClipクラスのgetDepth、_root.getNextHeighestDepthsあたりで深度を取得する。
その後、createEmptyMovieClipで、指定した深度にムービークリップを配置できる。
ただし、もとからその深度に何かある場合はそれは上書きされてしまうので注意。
もし、深度をあとから変更したい場合は空のムービークリップを配置して、swapDepthで深度を入れ替えてあげる。

タイムラインから取れるthisと_rootは同じ

どちらとも型はムービークリップ

trace(this == _root); // true