document.elementFromPointの挙動

案件で初めてdocument.elementFromPointを使ってみたけど、若干ハマったのでメモ。
本来、このメソッドは「画面に見えている範囲で、引数に与えられた位置に存在する要素を返す」というものなのだけど、この位置指定がずれる現象が。

現象を確認したのは、Android4.2.1のGoogle Chrome。(Galaxy Nexus)
このブラウザでだけ、なぜか位置指定がずれる。どれくらいのずれかを検証していたら、touchmoveのpageXとpageYの値にdevicePixelRatioを掛けてやると期待した要素が返ってきた。

推測だけど、イベント中の座標とelementFromPointで計算する座標系が違うんだと思う。(後者はpixel ratioを考慮した座標?)

まだ複数の端末で動作検証できていないので違うかもしれないけど、上記端末・ブラウザではとりあえず正常に動くことを確認。

▼参考
https://code.google.com/p/chromium/issues/detail?id=141840

Android3.x系以降で、プロキシ・サーバを設定する方法

http://denpa-shinbun.com/keitai/android-wi-fi-proxy.html

この記事を見て知りました。
Wi-Fiの設定画面で接続しているネットワーク名を長押しするとメニューが出現、そこの「ネットワーク設定」を選択すると、中にプロキシを設定する箇所があります。

長押しとか気づかないよ・・。

prefix付きpropertyの統一性のなさ

今日、-webkit-transformとか文字列で渡されたときに、それが有効なプロパティかどうかチェックする方法を考えてた。

結論から言うと、WebKit, Moz, MSで統一性がないことを知った・・。

var div = document.createElement(‘div’);
(‘-webkit-transform’ in div.style) //=> true
(‘webkitTransform’ in div.style) //=> true
(‘WebkitTransform’ in div.style) //=> true

(‘-moz-transform’ in div.style) //=> false
(‘mozTransform’ in div.style) //=> false
(‘MozTransform’ in div.style) //=> true

(‘-ms-transform’ in div.style) //=> true
(‘msTransform’ in div.style) //=> true
(‘MsTransform’ in div.style) //=> false

せめてどれかひとつでも共通で使える形があればいいのに・・。

mouseout / mouseoverのrelatedTargetの意味

relatedTargetの意味をちゃんと考えたことなかったので改めてまとめてみる。
relatedTargetは、要は「イベントが発生するきっかけになった要素」と言える。

実際の挙動については↓
http://jsdo.it/edo_m18/arCZ

mouseoutの場合

mouseoutが発生するということは、入れ子はどうあれなにかしらの要素から出たことを意味する。そして逆を返せばなにかしらの要素に入ったことを意味する。 そしてmouseoutのrelatedTargetはこの「なにかしらの要素に入った」要素が参照される。

mouseoverの場合

mouseoverの場合はmouseoutとまったく逆のことになる。 つまり、なにかしらの要素に入った時に発火し、逆を返せばなにかしらの要素から「出た」ことになる。 そしてrelatedTargetはこの、「なにかしらの要素から出た」要素を参照している。

PhoneGap開発で、Xcodeにエラーを表示する

PhoneGapで開発を行なっていると普通はXcodeにWebViewのエラーが表示されない。
console.logで指定した文字などは出るが、エラーで止まってしまうとなにが原因で止まったのかが一切わからなくなってしまう。

そこで、windowでエラーをトラップし、エラーの中身をconsole.logで出力すればどんなエラーが起きたかが確認できる。
これだけでだいぶデバッグがしやすくなる。

※ただ、他にもっといい方法がありそうな気はするので、なにか知っている人いたら教えてください(´・ω・`) 

window.onerror = function (e, file, num) {
    console.log('/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/');
    console.log(e);
    console.log('Error on ' + file + ' at Line: ' + num);
    console.log('/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/');
};

SenchaTouchのitemsは空にしない

当たり前のことなのかもしれないけど、ちょっとハマったのでメモ。
SenchaTouchのviewの部分で、途中からロジックを変更したせいで、空のitemsをconfigに残したままにしていた。

しかしこれが思わぬトラブルに・・。

itemsに空の配列を渡すと、空白のcontainerオブジェクトが自動で生成されそれが追加される模様。
そのため、初期化の段階で実際に表示したいviewを生成してaddしてやってもなぜか表示されない、という自体に。

(ちなみに、

view.down('*').destroy()

を実行すると自動で生成された空の要素が削除され、表示したい要素がちゃんと表示された)

なので、初期化でなにかしたい場合はitemsに空の配列を指定しないほうが◯ 

タグ: senchatouch

PhoneGapでiWebInspectorを使用するための準備

Refer to: http://www.mobilexweb.com/blog/debugging-web-safari-phonegap-iphone-ipad

PhoneGapで書きだされたAppのデバッグをするのに、iWebInspector が便利。

これを有効化するには、以下の1行を該当のメソッド内に記述する必要あり。

※注意! リリース前に削除すること!

【AppDelegate.mというファイル内にある、didFinishLaunchingWithOptions というメソッド内】

// Remove me after debugging
[NSClassFromString(@"WebView") _enableRemoteInspector];

Sencha Touch2のstoreでハマった話

Sencha Touch2のstoreでlocalStorageを使うとバグがあるらしい。(この記事を参考にしました

storeにadd()してsync()で簡単保存〜♪ とか思っていたらまったく保存される形跡がない。。
んで色々調べていたら、どうやらバグがあって保存されないかも、みたいな記事が。(これだけで数時間使ったョ・・・)

で、Modelにproxyを設定して、Ajaxで取得したrecord群をeachで回して毎回Modelを生成しつつ、save()を実行していくとしっかりと保存された。取得して表示するのも問題なさげ。これでやっと先に進める・・。 

とりあえずコード断片を残しておく。

Ext.define('Hoge.store.Loader.Twitter', {
    extend: 'Ext.data.Store',
    config: {
        autoLoad: true,
        model: 'Hoge.model.TwitterData',
        listeners: {
            load: function (records) {
            
                records.each(function (record) {

                    var model = Ext.create('Hoge.model.TwitterData', record.data);
                    model.save();
                });
            }
        },
        proxy: {
            type: 'jsonp',
            url: 'https://api.twitter.com/1/favorites.json?screen_name=*****',

            reader: {
                type: 'json'
            }
        }
    }
});


Sencha SDKでハマったのでメモ

まず、Sencha SDK toolsをインストール。
続いて Sencha Touch 2 をDL。

Sencha SDKはApplicationフォルダにインストールされます。
そしてプロジェクトを開始したい場所に移動し、そこにDLしてきたSencha Touch 2のzipファイルを解凍します。

生成されたフォルダ(sencha-touch-VERSION)に移動します。

そしてsenchaコマンドを叩けばいいのですが、いくつか事前準備をしておかないとエラーが出ます。
まず、どうやらzshを使っている人はインストール時にうまくパスを通してくれないらしく、自分でパスを通さないといけません。

export PATH=/Applications/SenchaSDKTools-2.0.0-beta3/command:$PATH
export PATH=/Applications/SenchaSDKTools-2.0.0-beta3/jsbuilder:$PATH
export PATH=/Applications/SenchaSDKTools-2.0.0-beta3/appbuilder:$PATH
export PATH=/Applications/SenchaSDKTools-2.0.0-beta3:$PATH
export PATH=/Applications/SenchaSDKTools-2.0.0-beta3/command:$PATH
export PATH=/Applications/SenchaSDKTools-2.0.0-beta3/jsbuilder:$PATH
export PATH=/Applications/SenchaSDKTools-2.0.0-beta3/appbuilder:$PATH

こんな感じ。
そしてさらに、SENCHA_SDK_TOOLS_2_0_0_BETA3という変数にもSDKのパスを設定しないといけません。(これに気づかずにだいぶ時間かかった・・)

export SENCHA_SDK_TOOLS_2_0_0_BETA3="/Applications/SenchaSDKTools-2.0.0-beta3"

ここまでの準備でやっとsencha generateが実行できるようになります。
最後に、以下のコマンドを叩いてやればベースとなるファイル群が生成されます。

$ sencha generate app APP_NAME PATH/TO/PROJECT

e.g.)

sencha-touch-2.0.0$ sencha touch app myApp ../myApp
タグ: sencha touch SDK

GoogleMaps APIのカスタムオーバーレイで独自バルーンを作る

手順

  1. ベースのクラスを作る
  2. ベースクラスをgoogle.maps.OvarlayViewのサブクラスにする
  3. drawメソッドを実装する
  4. panes_changedメソッドを実装する
  5. ベースクラスのコンストラクタ内で、setMap(map);を実行する

まとめるとこんな感じ↓

function Base(map){
    ...
    this.setMap(map);
}

Base.prototype = new google.maps.OverlayView();
Base.prototype.panes_changed = function () {
    ...
    var panes = this.get('panes');
    var div = document.createElement('div');
    panes.floatPane.appendChild(div);
};
Base.prototype.draw = function () { ... };

必要メソッドはこんな感じ。
panes.floatPaneのところは、他にも貼り付けるタイプによって異なるみたい。詳細はリファレンスを参照。

[Reference] Custom overlay reference
[参考] Google mapsでカスタムの吹き出し