jQuery.flickSimple.js Android版 Firefox等に対応しました。
何気なく見ていたのですが、このスライドでも jQuery.flickSimple が紹介されていることを知りました。
確かにそうですね。これまでの jQuery.flickSImple.js は Firefoxで動作していなかったようです。という訳で、また jQuery.flickSimple.js に手を加えましたので、お知らせします。
これまで、Webkitブラウザ以外は眼中に無かった(=jQuery.animate()でアニメーションするようにしていた)ので、ベンダープリフィックス「-webkit-」のCSSしか指定していませんでしたが、「-moz-」や「-o-」「-ms-」といったベンダープリフィックスに対応するように更新してみました。前回の「Androidでの表示パフォーマンスを向上」した件とあわせて、また少し使いやすくなったのではないかと思っております。
一部のブラウザではまだ動作確認ができていませんので、何か不具合があればお知らせいただけるとありがたいです。
jQuery.flickSimple Androidでの表示パフォーマンスを向上しました。
jQuery.flickSimpleを更新し、Androidでの表示パフォーマンスを向上しました。
久しぶりに自分のブログを更新したので眺めていたら、以下のサイトで jQuery.flickSimple が取り上げられているのを見つけました。
スマートフォン向けスワイプ・フリック系ライブラリのまとめ | BALLOG
#イトーヨーカドーとかのサイトに使われているなんて、まったく知りませんでした。取り上げていただき、また有用な情報を掲載していただき、ありがとうございます。>BALLOGの方
「Androidでの動作」が「△」で、他と比べてイマイチなんだそうです。これではイカンと思い「◯」になっているライブラリがどのような実装になっているのか拝見したところ、みなさん CSSアニメーション(-webkit-transform: translate())を使用しているようですね。
以前は、iOSの場合は -webkit-transform: translate3d() を、Androidを含むその他の場合は jQuery.animate() を使用してアニメーションさせていました。Androidの場合 translate3d() を使うとおかしな挙動をすることがあったので、CSSアニメーション自体を使わない実装にしていたのですが、「translate3d()」でなく「translate()」であれば問題ないのですね。
実際、Android 2.3 の実機で比べてみたところ、確かに -webkit-transform: translate() の方がスムーズに動くようです。
という訳で、これまで Androidでイマイチなんだよなぁ、と思っていたみなさま、多少は良くなったと思いますので、お試しくださいませ。
10桁・13桁のISBNを相互に変換するPerlワンライナー
ISBN(世界的に使われている書籍の識別番号)には、10桁のものと13桁のものがあります。
http://ja.wikipedia.org/wiki/ISBN
仕事でISBNを相互に変換するプログラムが必要になったのですが、CPANモジュール(Business::ISBN)を使うほどの処理でもないし、単純な実装のものが見つからなかったので自前で実装しました。ついでに、これワンライナーでも書けるんじゃね、と思い立ったのでPerlのワンライナーも作ってみました(ちょっと冗長なのでワンライナーにする意味はあまり無かったかなぁとも思いつつ)。
ISBN-13 → ISBN-10
perl -le '@a=map{$s+=(10-$i++)*$_;$_;}(grep{/\d/}split(//,shift))[3..11];$d=(11-$s%11)%11;print @a,$d==10?q{X}:$d' [ISBN]
ISBN-13 → ISBN-10(ハイフン付き)
perl -le '@a=map{$s+=(10-$i++)*$_;$_;}(grep{/\d/}split(//,shift))[3..11];$d=(11-$s%11)%11;printf(qq{%d-%d%d%d%d-%d%d%d%d-%d\n},@a,$d==10?q{X}:$d' [ISBN]
ISBN-10 → ISBN-13
perl -le '@a=map{$s+=($i++%2?1:3)*$_;$_;}(grep{/\d/}split(//,shift))[0..8];print 978,@a,(10-($s+8)%10)%10' [ISBN-10]
ISBN-10 → ISBN-13(ハイフン付き)
perl -le '@a=map{$s+=($i++%2?1:3)*$_;$_;}(grep{/\d/}split(//,shift))[0..8];printf(qq{978-%d-%d%d%d%d-%d%d%d%d-%d\n},@a,(10-($s+8)%10)%10)' [ISBN-10]
[ISBN-13] あるいは [ISBN-10] を実際の ISBNに置き換えて実行してください。指定するISBNは、ハイフン有りでも無しでも構いません。
ワンライナーですので、エラー処理などはしていません。不正なISBNを渡すと不正な値を返すと思います。
ちゃんと書くと、以下のようになるのでしょうかね。
# ISBN13 → ISBN10 sub isbn13_to_10 { my ( $isbn, $hyphen ) = @_; $isbn =~ s/\D//g; return if ( ! $isbn || $isbn !~ /^\d{13}$/ ); my @isbn10 = (split(//, $isbn))[3..11]; push @isbn10, isbn10_digit( @isbn10 ); return sprintf( "%d-%d%d%d%d-%d%d%d%d-%d", @isbn10 ) if ( $hyphen ); return join( '', @isbn10 ); } # ISBN-10 のチェックディジットを求める sub isbn10_digit { my @ints = @_; my $i = 0; my $sum = 0; foreach my $int ( @ints ) { $sum += (10 - $i) * $int; $i++; } my $digit = ( 11 - $sum % 11 ) % 11; return ($digit == 10 ? 'X' : $digit); } # ISBN10 → ISBN13 sub isbn10_to_13 { my ( $isbn, $hyphen, $prefix ) = @_; $prefix ||= '978'; $isbn =~ s/[^0-9x]//ig; return if ( ! $isbn || $isbn !~ /^\d{9}[0-9x]$/i ); my @isbn13 = ( split(//, $prefix), (split(//, $isbn))[0..8] ); push @isbn13, isbn13_digit( @isbn13 ); return sprintf( "%d%d%d-%d-%d%d%d%d-%d%d%d%d-%d", @isbn13 ) if ( $hyphen ); return join( '', @isbn13 ); } # ISBN-13 のチェックディジットを求める sub isbn13_digit { my @ints = @_; my $i = 0; my $sum = 0; foreach my $int ( @ints ) { $sum += ($i % 2 ? 3 : 1) * $int; $i++ } return ( 10 - $sum % 10 ) % 10; } # ISBNとして正しくない場合、正しいISBNを返す # 正しいISBNを求められない場合は、-1 を返す sub isnt_isbn { my $isbn = shift; $isbn =~ s/[^0-9x]//ig; return -1 if ( ! $isbn ); if ( $isbn =~ /^\d{9}[0-9x]$/i ) { my @arr = (split(//, $isbn))[0..8]; my $isbn10 = join( '', @arr, isbn10_digit( @arr ) ); return $isbn10 if ( uc( $isbn ) ne $isbn10 ); return; } elsif ( $isbn =~ /^\d{13}$/ ) { my @arr = (split(//, $isbn))[0..11]; my $isbn13 = join( '', @arr, isbn13_digit( @arr ) ); return $isbn13 if ( $isbn ne $isbn13 ); return; } return -1; }
jQuery.flickSimple 縦フリックに対応しました。
iPhoneの特徴的なインタフェースであるフリック操作を、iOS、Android、PC上のブラウザで実現するjQueryプラグイン、jQuery.flickSimpeをアップデートしました。
今回のアップデートの目玉は、縦フリック対応です。
#縦だとフリックとは言わないのですかね。この辺りの操作の名前がよくわかりません・・・。
iPhone、Androidで、overflow: scroll; にしたい時のスクロールの処理にも使っていただけると思います。
現時点で、まだAndroidの実機での動作が確認できていません。上手く動かないようであれば、お知らせをいただければと思います。また、お急ぎであれば、古いバージョンをお使いいただければと思います。
Jedit X で Markdown(とついでにPOD)
Markdownとは?
Markdownとは「軽量マークアップ言語の1つ」で、簡単な記法で書いたテキストをHTMLに変換してくれる仕組みです。Wikiや「はてな記法」みたいなものですね。
「Markdown」というものがあることは知っていたのですが、githubの「README.md」がこの方式だったので、改めて記法などを調べてみた訳です。HTMLを埋め込めるなど、マニュアル等を作るのに使いやすそうですね。
既にいろんなCMSやテキストエディタがMarkdownに対応しているそうですが、愛用のテキストエディタ「Jedit X」についての情報は見つけられなかったので、例のようにJedit Xのマクロ(=AppleScript)を作ってみました。
Markdown を Safariでプレビュー
Markdownのオリジナル版はPerlで実装されていて、以下でダウンロードできます。
http://daringfireball.net/projects/markdown/
まずはこれを入手して、「Markdown.pl」を Jedit X の「scripts」フォルダ(~/Library/Application Support/Jedit X/scripts/Markdown.pl)に入れておきます。
で、以下のようにAppleScriptを書きました。
tell document 1 of application "Jedit X" save set fPath to path as POSIX file set pPath to POSIX path of fPath set tmppath to pPath & ".preview.html" set existsflg to false tell application "Finder" set existsflg to exists file tmppath as POSIX file end tell if not existsflg then set scpt to "perl ~/Library/Application\\ Support/Jedit\\ X/scripts/Markdown.pl " & quoted form of pPath & " > " & quoted form of tmppath do shell script scpt tell application "Safari" activate open tmppath as POSIX file end tell delay 1 do shell script "rm -f " & quoted form of tmppath end if end tell
上記を「AppleScriptエディタ」にコピペして、「MarkdownをSafariでプレビュー.scpt」とかの名前で保存、Jedit Xの「スクリプトウィンドウ」に放り込めば完成です。
元のファイル名に「.preview.html」を加えたファイルをテンポラリファイルとして作ってます。無闇に上書きしてしまうとまずいので、既に同名のファイルがある場合には何もしないようにしてあります。
Safariでプレビューしますが、他のブラウザがよければ、「tell application "Safari"」のくだりをお好きなブラウザに書き換えてもらえばよいですね。ちなみに、Chrome の場合は、
tell application "Google Chrome" activate -- open tmppath as POSIX file open location "file://" & tmppath end tell
としないと開きませんでした。
ついでに POD も。PODをSafariでプレビュー
同じような軽量マークアップ言語の1つとして「POD = Plain Old Documentation」というPerlを書く人にはお馴染みの記法があります。これも同じようにできるなぁ、と思ったので作ってみました。
Mac OS X であればデフォルトで「pod2html」というコマンドが入っていますので、こちらはダウンロードとかする必要はありません。
tell document 1 of application "Jedit X" save set fPath to path as POSIX file set pPath to POSIX path of fPath set tmppath to pPath & ".preview.html" set existsflg to false tell application "Finder" set existsflg to exists file tmppath as POSIX file end tell if not existsflg then set scpt to "pod2html " & quoted form of pPath & " > " & quoted form of tmppath do shell script scpt tell application "Safari" activate open tmppath as POSIX file end tell delay 1 do shell script "rm -f " & quoted form of tmppath do shell script "rm -f ./pod2htmd.tmp" do shell script "rm -f ./pod2htmi.tmp" end if end tell
ちなみに、両方ともプレビューするだけなので出力したHTMLは消しちゃっていますが、出力するためのスクリプトも登録しておくと便利かもしれませんね。
iPhone と Android の onOrientationChange タイミングの違い
Androidのブラウザにて。Android 2.2から、iPhoneと同じように縦持ち・横持ちが変わった際に発生するイベント「window.onorientationchange」が使えるようになっているようです。ですが、このイベントが起きるタイミングがiPhoneとAndroidで異なっているようです。
var $win = $(window); var debug = $('#debug'); $win.bind( 'orientationchange', function() { debug.html( debug.html() + 'orient:' + $win.width() + ', ' ); } ) .bind( 'resize', function(){ debug.html( debug.html() + 'resize:' + $win.width() + ', ' ); } );
上のJavaScriptを実行すると、iPhoneの場合は、
- ウィンドウのサイズ変更 → resizeイベント → orientationchangeイベント
という順番でイベントが発生していることがわかります(なんだか、resizeイベントが2回発生するケースもあるみたい)。
ところが Android 2.2の場合は、
- orientationchangeイベント → ウィンドウのサイズ変更 → resizeイベント
という順番になります。
ちなみに、Android 2.1以前は、typeof window.onorientationchange === 'undefined' なので、
- ウィンドウサイズの変更 → resizeイベント
となっています。
orientationchangeイベントだけだと、iPhoneの場合は変更後の、Androidの場合は変更前の値を持ってきてしまうことになりますので、ウィンドウサイズを元に表示を変更しようとした場合にはおかしなことになってしまいます。以下のように判定をしている場合には、注意が必要ですね。
if ( typeof window.onorientationchange === 'object' ) { $(window).bind( 'orientationchange', function(){ hoge(); } ); } else { $(window).bind( 'resize', function(){ hoge(); } ); }
Androidの場合には、resizeイベントを使うようにすると、iPhoneと共通化ができると思います。
var isAndroid = navigator.userAgent.indexOf('Android') != -1; if ( typeof window.onorientationchange === 'object' && ! isAndroid ) { $(window).bind( 'orientationchange', function(){ hoge(); } ); } else { $(window).bind( 'resize', function(){ hoge(); } ); }
ちなみにAndroidのresizeイベントは、アドレスバーが表示されている間はスクロールするだけで発生するようなので、重い処理はさせないほうが良さそうです。
Androidのタップ ハイライトについて
Androidのブラウザにて。Android 2.2 までと 2.3 で、アンカーやonclickイベントの付与された要素(エレメント)をタップした時に付くハイライトの挙動が変わっています。
Android 2.2 までは、以下のようになっているようです。
a) アンカーには、全てハイライトが付く。
b) onclickイベントが付与された要素には、ハイライトが付く。
c) 親要素にonclickイベントが付与されている場合、子要素にクリック可能な要素(アンカータグ、またはonclickイベントが付与された要素)が "1つしか存在しない場合" は、親要素がハイライトされる。2つ以上クリック可能な要素がある場合には、個別にハイライトされる。
a) ・ b) はいいとしよう。ハイライトを見せたくない場合には、以下のCSSで消すことができます。
-webkit-tap-highlight-color: rgba(0,0,0,0);
c) については、具体例を挙げると、
<div id="oya" onclick="hoge();"> <a href="hoge.html">兄</a> | <a href="hoge.html">弟</a> </div>
上記の場合は、「兄」と「弟」がそれぞれハイライトされます。これは問題ない。
<div id="oya" onclick="hoge();"> <a href="hoge.html">子供</a> </div>
上記の場合、「子供」をタップしても、<div id="oya">〜</div>がハイライトされてしまいます。子要素のonclickイベントで、event.stopPropagation();(イベントのバブリングを中断)するようなケースもよくあるので、これは困った仕様ですね。
なんでこんな仕様にしてしまったのだろう・・・。ますますAndroidが発展途上のOSに思えてくる。
ちなみに、Android 2.3からは仕様が変わっています。