ラベル クロスブラウザ の投稿を表示しています。 すべての投稿を表示
ラベル クロスブラウザ の投稿を表示しています。 すべての投稿を表示

2008-10-15

Golazo MA4 で Google ストリートビューを使って、メモの位置の風景を確認できるようにしました。

Golazo MA4 team のなかじまんです。新機能のお知らせです。

Golazo MA4 でメモを表示するとき、そのメモの位置を表す Google マップに加え、Google ストリートビューを表示して、その位置の風景を確認できるようにしてみました。

↓次のスクリーンショットのとおりです。

今回は、ココメモの "よく読む" のリンク先だけ対応しました。今後は、ココメモの追加や編集でも対応する予定です。



Google ストリートビューは、日本の主要都市しか対応していません。ですので、Golazo MA4 では、ストリートビューを表示できる位置(つまり、データが存在するとき)だけ、ストリートビューを表示する工夫をしてみました。

↓ソースコードを抜粋したものです。

// GStreetview
var pano = new GStreetviewPanorama(document.getElementById('pano'));

var client = new GStreetviewClient();
client.getNearestPanoramaLatLng(point, function(latlng) {
if (latlng) {
$('#pano').show();
pano.setLocationAndPOV(point);
}

GStreetviewPanorama オブジェクトを生成するとき、オプションの緯度経度をを与えません。そして、ストリートビューを表示する div 要素は、事前に display:none; で非表示としています。

GStreetviewClient オブジェクトの getNearestPanoramaLatLng メソッドを使って、メモの位置(point 変数がそれ)付近に、ストリートビューのデータがあるかどうか問い合わせています。

メモの位置付近にデータ(latlng 変数がそれ)が存在するときは、前述の div 要素を表示し、GStreetviewPanorama オブジェクトの setLocationAndPOV メソッドを使って、その位置のストリートビューを表示しています。メモの位置付近にデータが存在しないときは、何もしないので、ストリートビューは表示されなことになります。

Google ストリートビュー APIのノウハウをいくつか tips [okyuu.com] がとても参考になりました。ありがとうございます。

今回は、ただ単に、ストリートビューを表示するだけで、地図との連携といったインタラクティブな機能はありません。どのような機能や操作性が有益なのか、まだ掴めきれていませんので、よいアイディアがありましたら、ぜひ教えてください。

注意点です。主要な OS とブラウザで動作確認しましたが、MacOS X の Firefox2 だとストリートビューが表示されない現象を確認しています。また、古いバージョンの Flash Player だと、ストリートビューを操作するとき、JavaScript エラーが発生することがあります。Flash Player 9 以上をオススメします。

2008-09-30

CSS Browser Selector を使って Google Chrome を個別対応する。textarea のフォントサイズの相対値がおかしな件。

Google Chrome だけ textarea の font-size がひとまわり小さくなってしまう
Google Chrome を使って Golazo MA4 の動作確認をして気が付いたのですが、Google Chrome だけ、次のように textarea の font-size がひとまわり小さく表示されてしまうのです。em 単位で指定してるのが良くないのかなぁ。ネットで調べてみたのですが、それらしき話題は見つかりませんでした。時間があるときに原因を調べてみます。
引き続き、調べてみました。Google Chrome の textarea は、気になるところが2点ほどあります。

1つ目は、textarea のフォントサイズが、他のブラウザに比べて、ひとまわり小さいことです。他のブラウザに比べて 80% くらいの大きさでしょうか。Styling even more form controls を使うと、様々なフォームのスタイルを手軽に確認できます。

2つ目は、次のように textarea のフォントサイズに相対値を指定すると、元々の textarea のフォントサイズに対して .8em 分、小さく表示されるということです。CSS の仕様は、あまり詳しく把握できていないのですが、.8em と指定したときは、1em に対する .8em のフォントサイズになると理解しているのですが、どうもそうじゃないようです。Safari 3.1 だと期待どおりなのですが...。

#content form input,
#content form textarea {
font-size: .8em;
}

次のとおり、フォントサイズに絶対値を指定すると、Google Chrome も含め、すべてのブラウザで、期待どおりのフォントサイズで表示できます。ただし、フォントサイズを固定すると、文字サイズの拡大と縮小で、ブラウザ間で差異が出てしまう(特にIE)ため、対処としては不完全といえます。

#content form input,
#content form textarea {
font-size: 13px;
}

Google Chrome だけ個別に対応する手法(いわゆる CSS Hack)がないか探してみましたが、Google Chrome は Safari 3 の CSS Hack を適用できるが、Google Chrome だけ適用できる CSS Hack はなさそうでした。Google Chrome を調整すると Safari 3 に影響が出ちゃうということですね。う~む。

ということで CSS だけでの対応はあきらめ、CSS Browser Selector という JavaScript を使って、User-Agent ごとに CSS を切り替える仕組みを使って対応することにしました。

CSS Browser Selector の導入はとても簡単です。次のように JavaScript をロードして、

<script type="text/javascript" src="css_browser_selector.js"></script>

次のように、ブラウザごとに CSS を記述するだけです。Google Chrome だけ textarea のフォントサイズを 1em にしています。これで、すべてのブラウザで、ちょうど 80% の大きさになります。

#content form input,
#content form textarea {
font-size: .8em;
}

.chrome #content form textarea {
font-size: 1em;
}

CSS Browser Selector が何をするかというと、navigator.userAgent を見分けて、HTML 要素にブラウザの種類を表すクラス名を動的に追加するというだけです。ブラウザのエンジン、オペレーティングシステムの区別もできます。なかなかシンプルなアイディアに感心します。

<html class="gecko ff2 win js">

JavaScript が無効だと使えないという欠点がありますが、JavaScript の有無による CSS の区別も備えるため、JavaScript が無効なときの妥協的な CSS を用意するといった対応もできます。

2008-09-29

Google Chrome だけ textarea の font-size がひとまわり小さくなってしまう

Google Chrome を使って Golazo MA4 の動作確認をして気が付いたのですが、Google Chrome だけ、次のように textarea の font-size がひとまわり小さく表示されてしまうのです。



次のように、その他のブラウザ (画像は Firefox2) では、だいたい同じ大きさで表示されます。



font-size を指定するスタイルシートは、次のとおりです。

#content form input,
#content form textarea {
font-size: .8em;
}

em 単位で指定してるのが良くないのかなぁ。ネットで調べてみたのですが、それらしき話題は見つかりませんでした。時間があるときに原因を調べてみます。ひとまず、デザインに方針に影響を与えそうなので、事象だけお伝えしときます。

2008-09-19

メディアクエリによる iPhone スタイルの切り替えは万能じゃないのか?

メディアクエリを使って iPhone (iPod touch を含む) とその他のブラウザで、スタイルシートを切り替えようと試みているのですが、Apple の開発者サイトやネット上で紹介している方法だと、なぜか Safari 2.0.4 (Multi-Safari) が期待どおり振る舞ってくれません。

次のとおり link 要素を記述しました。ですが、

<link media="only screen and (min-device-width:480px)" rel="stylesheet" type="text/css" href="/css/golazo-iphone.css" />
<link media="screen and (min-device-width:481px)" rel="stylesheet" type="text/css" href="/css/golazo.css" />

IE6 と IE7 がスタイルシートを読み込まなかったため、次のとおり [if IE] .. [endif] を追加して個別に対応しました。

<link media="only screen and (min-device-width:480px)" rel="stylesheet" type="text/css" href="/css/golazo-iphone.css" />
<link media="screen and (min-device-width:481px)" rel="stylesheet" type="text/css" href="/css/golazo.css" />
<!--[if IE]>
<link rel="stylesheet" type="text/css" href="/css/golazo.css" />
<![endif]-->

これで OK という気になっていたのですが、MacOS X Tiger の Safari 2.0.4 (Multi-Safari) を使ってみると、どのスタイルシートも読み込まれないのです。[if IE] .. [endif] はコメントでスキップしているので、つまり、メディアクエリを指定した link 要素をスキップしているということです。

何か方法が悪いのか、勘違いしているのか、自分自身の中で謎が深まっていくばかりです。Safari 2.0.4 (Multi-Safari) 固有の振る舞いなんでしょうか。今となっては Safari 2.0.4 を試す環境がないので、確認もできないのです。困りました。ヘルプみー。

追記です。-- 2008-09-19

明確な記述のある文献は見つかっていないのですが、ネット上などの情報を総合すると、Safari 2.0.4 の時点では、メディアクエリに対応していなかったようです。

ですので、1~1.5世代くらい前のブラウザも範疇に含める必要があるなら、UserAgent を見分けた切り替えが妥当という結論です。う~む。やっぱり、何らかのプログラム的な要素が必要になりますね。

2008-06-08

jQuery JSONP プラグインを改善してアップデートしました

コールバックのイベントハンドリングを容易にする jQuery JSONP プラグインを改善してアップデートしました。使い方とソースコードを確認 し、必要に応じてダウンロードして差し替えてください。

変更点は、次のとおりです。コールバックのインタフェースに変更があります。

jQuery 1.2 から script 要素を jQuery.fn.append すると、キャッシュを抑止するための意図しないパラメータが付いてしまう ため、jQuery を使わず、script 要素を直接 appendChild で追加するようにしました。
  jQuery('head', document)[0]
.appendChild(script[0]);
file:// を使ったり、キャッシュが効いているとき、IE がクラッシュしないように script 要素の削除を 10ms 遅らせる ようにしました。
  setTimeout(function() {
script.remove();
}, 10);
jQuery の流儀にしたがい、コールバックのコンテキストが jQuery オブジェクトの要素になるようにしました。
  self.each(fn, [json]);
jQuery 1.2 から jQuery.getJSON メソッド を使って同じ機能が実現できる ため、このプラグインは不要になったのですが、今まで使って慣れ親しんできたのと、ちょっとした愛着があるので、使い続けていきます。

2008-05-27

いにしえの window.undefined ... jQuery の場合

JavaScriptにおける未定義値の判別方法
jQueryのundefined変数による判別は謎です。undefinedはECMA-262 3rdやJavaScript 1.3にGlobalオブジェクトの値プロパティとして定義されていました。もっとちゃんと調べないと。反省)。jQueryはこの判別方法を使っているので知らずに書き換えると予期しない動作をします…。
aquilegia さんの投稿の中で、jQuery の window.undefined の実装に対して疑問があった(過去形)ようなので、その経緯を調べてみました。

その経緯は jQuery General Discussion の中にそれらしき議論がありました。どうやら、window.undefined というグローバルオブジェクトは、jQuery 1.0 の開発中に導入したものらしいです。

もともとは、undefined と判定すべき箇所が、null 判定していたことに起因するようです。
foo === null は foo === undefined の誤りでは?
ですが、undefined は IE5.0 とそれ以前では使えない ので、次のように表現し直そうとしたみたいです。
typeof foo === 'undefined' 
ですが、この表現を好まないとして、次のように window.undefined を用意したようです。
window.undefined = window.undefined;
これにより、IE 5.0 とそれ以前を含む古いブラウザでも undefined が使えるようになって、かつ ECMA-262 3rd の undefined グローバルオブジェクトの要件も満たすということです。

次のようにしても、同じ効果があるとの説明もありました。スコープの影響を受けるので、汎用ライブラリには向かないかもしれませんね。
var undefined;
で、aquilegia さんが提案するとおり、undefined の判定は void 演算子を使うのが確実そうなんですが、IE 3 まで遡ると void 演算子がない ようですね。

だとすると、jQuery の window.undefined という実装は、undefined の書き換えの不都合は抱えますが、かなり広範囲でブラウザの互換性を実現する手段となっているということになりますね。

ちょっと専門外の話題に言及したので、知識が曖昧な部分があったかもしれません。誤りがあれば aquilegia さんが訂正してくれるだろうと期待してます。

2008-05-21

Safari と Opera でキーボードを使ってアンカーを移動する方法

ページ上のアンカーテキストにフォーカスが移ったとき、その a 要素の onfocus イベントをハンドリングして、その中からさらにページの要素を操作するといった JavaScript コードを書いています。

この JavaScript コードを Safari 3.1 と Opera 9.2 でテストしようとしたところ、TAB キーだとアンカーを移動できないことを知りました。これだと、a 要素の onfocus イベントのテストがしにくいです。

そもそも Opera の TAB キーは、フォームの要素を移動するためのものだそうです。その変わりに Opera は、別のショートカットキーを用意しています。

a キーでアンカーを進み、q キーでアンカーを戻ります。Ctrl + ↑↓ キーも同じ動きをします。また、Shift + ↑↓←→ キーで、アンカーとフォームの要素を上下左右に移動できます。

Safari の TAB キーも、フォームの要素を移動するためのものだそうです。が、次のように、"タブキーを押したときに WEB ページ上の各項目を強調表示" オプションを ON に変更すれば、その動きを変えることができます。



オプションを ON にすると、TAB キーを使ってアンカーとフォームの要素を移動できるようになります。もちろん Shift + TAB キーで、その逆に移動できます。

2008-04-21

input要素を操作すると "このコマンドはサポートされていません" エラーになることがある

次のように JavaScript/jQuery を使って HTML フォームを動的に生成しようとすると、IE6 だと "このコマンドはサポートされていません" というエラーが発生します。
var form = $('<form />')
.addClass('editor');

$('<input />')
.addClass('small')
.attr('type', 'button')
.attr('value', 'OK')
.click(function() {
})
.appendTo(form);
Microsoft サイトから該当する技術情報が見当たらなかったのですが、どうやら input 要素の type 属性を変更しようとすると、このエラーになるようです。上記の JavaScript でいうと、type 属性に botton を指定する箇所が該当します。

ですので、HTML フォームを動的に生成するときは、DOM 操作ではなく、次のように innerHTML の仕組みを使って input 要素を生成する必要がありそうです。
var form = $('<form />')
.addClass('editor');

$('<input type="button" />')
.addClass('small')
.attr('value', 'OK')
.click(function() {
})
.appendTo(form);
ちょっと解せない感じは残りますが、この JavaScript は、他のブラウザでも期待どおり動作しています。

2008-04-05

ブラウザによって .innerHTML の結果が異なるので jTemplates に置き換えました

The geo microformat 生成ツールを公開しました
郵便番号、住所、場所、または画像の URL を入力すると、自動的に位置情報を取得します。そして、その結果から、ブログやホームページに貼り付けるための HTML を生成します。
先週公開した The geo microformat 生成ツール ですが、ブラウザによって生成する HTML にかなりの差が出てしまっていました。

IE6 だと、次のような HTML を生成していました。要素名が大文字で、属性値のダブルクオートがありません。
<SPAN class=geo>
<SPAN class=latitude>35.695204</SPAN>,
<SPAN class=longitude>139.701969</SPAN>
</SPAN>
Opera9 だと、次のような HTML を生成していました。要素名が大文字で、閉じ要素がありません。
<SPAN class="geo">
<SPAN class="latitude">35.689718,
<SPAN class="longitude">139.691699
このようなブラウザによる違いが出てしまったのは、Element.innerHTML (jQuery.fn.html) を使って HTML を取得していたのが原因でした。ソースコードを書くのを簡略化しようとサボったのがよくなかった。ちょっと反省です。

ブラウザによる Element.innerHTML の違いを吸収するのは現実的ではないので、HTML の文字列を自前で組み立てるようにしました。ただ、すべて自前で組み立てると XSS などの心配があるため、次のように、jTemplates プラグイン を使って、テンプレートから HTML を生成するようにしています。
var template = 
'<span class="geo">' +
'<span class="latitude">{$T.y}</span>, ' +
'<span class="longitude">{$T.x}</span>' +
'</span>';
return $.createTemplate(template)
.get({label: label, x: x, y: y }, {}, window);
そして、jTemplates プラグインを使って生成した HTML の文字列を、次のように、そのまま表示するようにしました。
$('.tabs-preview', tabs)
.html(geo);

$('.tabs-html', tabs)
.val(geo)
.focus(function() {
$(this).later(function() {
this.select();
}); // Safari
});
この対応で、The geo microformat 生成ツールをどのブラウザから 使っても、同じ HTML が生成されるようになりました。また、生成する HTML は XHTML に準ずるようにしました。

The geo microformat 生成ツールを公開しました
The abbr design pattern は、abbr タグを使います。IE6 は abbr タグに対応していないため、期待どおりの HTML が生成されず表示もできませんので、注意してください。
という不都合もありましたが、今回の対応で、自前で組み立てた HTML の文字列を Element.innerHTML (jQuery.fn.html) するようにしたため、abbr タグが無視されるようになり、見た目だけは表示されるようになりました。

そうそう。先ほど、"ブラウザによる Element.innerHTML の違いを吸収するのは現実的ではない" と書きましたが、この問題を解決しようとする jQuery プラグイン を見つけました。が、試してはいません。IE をターゲットとしているようです。

2008-03-08

Multi-Safari で Safari3 と Safari2 が共存できました

開発した WEB サイトや WEB アプリの動作確認のために Mac mini を所有してますが、MacOS X Tiger を最新にアップデートすると Safari3 に入れ替えバージョンアップとなって Safari2 が使えなくなる。その逆で、アップデートしないと Safari2 のままで Safari3 が使えないというジレンマがありました。

旧バージョンの Safari をスタンドアロンのパッケージとして配布するサイトがあると聞いたので、さっそく試してみました。

Multi-Safari
These special versions of Safari use the original Web Kit framework that came with them, bundled inside the application. They will mimic original Safari rendering and javascript behaviours. HTTP requests and cookies however are still handled by the system and may not work exactly the same.
使うのは簡単でした。Multi-Safari から希望するバージョンのパッケージをダウンロードして実行するだけです。試しに Safari 2.0.4 を使ってみましたが、確かに Safari 2.0.4 の振る舞いをしています。

旧バージョンの各 Safari に対応した WebKit を組み込んでいるようなので、HTML/CSS のレンダリングと JavaScript の動きは、旧バージョンそのものになるようです。ですので、WEB サイトや WEB アプリの動作確認にはもってこいです。

ただ、MacOS X のシステムとして扱っている部分は、旧バージョンそのものの動きとはならないかも?という制限があるようです。

あと、MacOS X のバージョンにも依存するようです。例えば、MacOS X Tiger で Panther 時代の Safari は不都合(動作しない?)があるなど、すべての旧バージョンが試せるというわけではありません。

動作条件や制限は Multi-Safari に記載がありますので、ダウンロードする前に確認してみてください。

MacOS X Tiger で Safari1.3 が動かせないのが残念ですが、Safari3 と Safari2 が共存できるだけでも、とても助かりますね。

JavaScript「クロスブラウザ」テクニック―どのブラウザでも、どのOSでも同じに動くスクリプトの“技” (Programmer’s lounge)JavaScript「クロスブラウザ」テクニック―どのブラウザでも、どのOSでも同じに動くスクリプトの“技” (Programmer’s lounge)
半場 方人


by G-Tools

2007-12-04

Safariで入力ボックスの貼り付け(ペースト)が無効にならない!?

Web Kit DOM Programming Topics の JavaScriptからのペーストボードの使用 によると、Safari は onpaste イベントを実装しているという解説があります。

しかし、実際に次のようなコードを Safari 2.0.4 (MacOS X) で試してみたところ、入力ボックスの貼り付け (Command+V) が期待しているように無効になりません。何か私に勘違いがあるのでしょうか。
// ignore_paste
function ignore_paste(name) {
var element = document.form[name];
if (element) {
element.onpaste = function() {
return false;
}
}
}
このコードは Safari 3 (Windows XP) では期待どおり動作しています。もちろん IE 6 と IE 7 (Windows XP) も同様に動作します。

それ以外のシェアの高いブラウザは、今のところ onpaste イベントをサポートしていないので、このコードは動作しないはずです。エラーにもならないはずです。試していませんが、聞くところによると Firefox 3 は onpaste イベントをサポートするとのことです。

[すぐにできる!] iLife'08[すぐにできる!] iLife'08
村上 弘子 白瀧 由裕 井村 克也

[すぐにできる!] iWork'08 [すぐにできる!] Mac OS X Version10.5 Leopard Macをはじめよう! Mac Basic Guide (アスキームック MacPeople MOOK 18) (アスキームック MacPeople MOOK 18) (アスキームック MacPeople MOOK 18) Mac OS X 10.5 Leopard Perfect Guide (アスキームック MacPeople MOOK 21) Mac Fan iLife '08[iTunes・iPhoto・iMovie・iDVD・GarageBand・iWeb]入門・活用ガイド (MacFanBooks)

by G-Tools

2007-11-30

入力ボックスに郵便番号のマスクを適用する方法(続編)

jQuery を使って、入力ボックスに郵便番号のマスクを適用する方法の続編を用意しました。

Alt+? キーの振る舞いを考慮するように修正し、Safari のフォーカスが移ったときテキストを選択できないという不都合にも対応しています。

入力ボックスに郵便番号のマスクを適用する #2

また、フォーカスを失ったとき、ハイフン付きの郵便番号となるよう辻褄を合わせるのは、ページのアンロード時に適用するのも有効であることがわかりました。

今まで試した結果に基づいて Postal Search Ajax API の jQuery lookup プラグインの1部として、入力ボックスに郵便番号のマスクを適用する機能を追加する予定です。$('#c').lookupable(); のように指定できるとよいかと思案中です。

2007-11-29

Safari onfocus イベントで select してテキストを選択する方法 (改善案)

テキストボックスにフォーカスが移ったとき、そのテキストを選択するという、次のような JavaScript コードはよく見かけますが、onfocus イベントの中で select メソッドを使うという方法だと、Safari 3 では期待どおり動作してくれません。

テキストを編集しようとしてクリックすると、一瞬そのテキストが選択されますが、すぐに選択が解除されてしまいます。ただ例外もあって、タブキーでフォーカスが移ったときは、期待どおり選択され、解除されることはありません。う~む。
<form id="f">
<input id="c" type="text" name="c" value="160-0021" />
<input type="submit" />
</form>

<script type="text/javascript">
//<![CDATA[
jQuery(function($) {

$('#c')
.focus(function() {
$(this).select();
});

}); //jQuery
//]]>
</script>
select メソッドは onfocus イベントが完了してから適用しないとダメのようです。ですので、次のように setTimeout 関数を使って、select メソッドの適用を遅らせてみたところ、期待どおり動作するようになりました。

<script type="text/javascript">
//<![CDATA[
jQuery(function($) {

$('#c')
.focus(function() {
var self = this;
setTimeout(function() {
$(self).select();
}, 10); // Safari
});

}); //jQuery
//]]>
</script>
理論上は onfocus イベントの中で select メソッドを適用していないので、そのタイミングによる副作用があること(ありそう)ですが、他のブラウザも含めて試行していますが、今のところ不都合は見つかっていません。

[すぐにできる!] iLife'08[すぐにできる!] iLife'08
村上 弘子 白瀧 由裕 井村 克也

[すぐにできる!] iWork'08 [すぐにできる!] Mac OS X Version10.5 Leopard Macをはじめよう! Mac Basic Guide (アスキームック MacPeople MOOK 18) (アスキームック MacPeople MOOK 18) (アスキームック MacPeople MOOK 18) Mac OS X 10.5 Leopard Perfect Guide (アスキームック MacPeople MOOK 21) Mac Fan iLife '08[iTunes・iPhoto・iMovie・iDVD・GarageBand・iWeb]入門・活用ガイド (MacFanBooks)

by G-Tools