はりまや日記

なんか適当にいろいろ綴ったりなんかするところ

iphoneアプリ開発日記その10

webview のリンク長押しをなんとかする 二日目

さて、前回までで リンク長押しのイベント取得と、その結果を native に返すことができた。
今日は、リンク URL を取得してみよう。


URL 取得

そもそも javascript をほとんどやってないので、どうやって取るのかイメージがさっぱりです。
ググっていると、参考になりそうなページをいくつか見つけた。

jQuery.Event - jQuery 日本語リファレンス
iPhone/Android/PC 対応。jQuery で書くタッチイベント (フェンリル | デベロッパーズブログ)

ほう、event.changedTouches[0].pageX で座標が取れるのか。
試してみよう

$( document ).ready( function()
		{
		var interval = 500;
		$( "a" ).bind( "touchstart", function()
			{
			timer = setTimeout(function()
				{
                                window.location = 'nativecode://touchstart/hoge' + event.changedTouches[0].pageX;
				}, interval);
			function clearFunction(){
			clearTimeout(timer);
			alert("touch cancel!");
			}
			$( "a" ).bind( "touchend touchmove touchcancel", clearFunction );
			});
		});

... 動かない。いやもう全然。
というかタップ自体認識しなくなってる。

んで、いろいろ試していたところ、上の階層なら event を取れることが判明

$( document ).ready( function()
		{
		var interval = 500;
                // この辺は event 生きてる
                alert(event.currentTarget);
		$( "a" ).bind( "touchstart", function()
			{
			timer = setTimeout(function()
				{
                // この辺はだめ
                                //alert(event.currentTarget);
                                window.location = 'nativecode://touchstart/hoge' + event.changedTouches[0].pageX;
				}, interval);
			function clearFunction(){
			clearTimeout(timer);
			alert("touch cancel!");
			}
			$( "a" ).bind( "touchend touchmove touchcancel", clearFunction );
			});
		});

んー、スコープの問題なのかなー
いろいろ試したところ、上の階層で変数に格納しておけば event は生きてるが、プロパティにアクセスできない。

$( document ).ready( function()
		{
		var interval = 500;
                var target = event.currentTarget;
		$( "a" ).bind( "touchstart", function()
			{
			timer = setTimeout(function()
				{
                                alert(target);//これは動く
                                //alert(target.type);//動かない
				}, interval);
//略

で、ここを見ていたら、こんな記述があった。

var target = $(event.target);

これでやってみると、target.type にアクセスができた。undefined だったけど。
一体これはなんなのだろう?


$(event.target) とはなんだったのか

ということで、$() について調べてみた
どうやら、「jqueryオブジェクト」という物のようだ。

このへんを参考にすると、
javascript のオブジェクトは、メソッドとプロパティを持っていて、
$() で記述すると、それは jquery のオブジェクトとして扱われると。
で、jquery のオブジェクトということがわかっているので、そのメソッドとプロパティにアクセス出来るようになる。

ざっくりこんな理解でいいのかな。
void型のポインタにキャストかました感じっぽいな。


タッチイベントから、 url と タイトルを取得する

まあ、そんなこんなでイベントのプロパティにアクセス出来るようになりました。

早速取得してみましょう

$( function()
	{
	var interval = 500;
        var target = $(event.currentTarget);
        var title = target.text();
        var url = target.attr('href')
 
	$( "a" ).bind( "touchstart", function()
		{
		timer = setTimeout(function()
			{
                        window.location = 'nativecode://touchstartxxx/' +url + title;
			}, interval);
//略

結果

2013-06-20 22:04:34.959 harafuwa[58944:11303]              url: nativecode://touchstartxxx/http://pad-soku.com/archives/29571047.html%20%20%20%E3%80%90%E3%83%91%E3%82%BA%E3%83%89%E3%83%A9%E3%80%91%E5%87%84%E3%81%99%E3%81%8E%E3%81%A6%E3%83%AF%E3%83%AD%E3%82%BF%EF%BD%97%EF%BD%97%E3%83%89%E3%83%AD%E3%83%83%E3%83%97%E3%81%A7%E5%A3%81%E7%B4%99%E3%82%92%E4%BD%9C%E3%82%8B%E8%81%B7%E4%BA%BA%E3%81%8C%E3%83%A4%E3%83%90%E3%81%99%E3%81%8E%E3%82%8B%EF%BD%97%EF%BD%97%EF%BD%97%20%E3%83%A1%E3%82%BF%E3%83%89%E3%83%A9%E9%80%9F%E5%A0%B1%20-%202013-06-20%2021:57:48
2013-06-20 22:04:34.960 harafuwa[58944:11303]           scheme: nativecode
2013-06-20 22:04:34.960 harafuwa[58944:11303]             host: touchstartxxx
2013-06-20 22:04:34.961 harafuwa[58944:11303]             path: /http://pad-soku.com/archives/29571047.html   【パズドラ】凄すぎてワロタwwドロップで壁紙を作る職人がヤバすぎるwww メタドラ速報 - 2013-06-20 21:57:48

取れた … けど文字多いなー
URLの文字数制限って4000文字くらいだっけ? まあ大丈夫か。

とりあえず取得できました。


ユニークなアプローチ

URL に長い文字列をくっつけるのがちょっと気持ち悪いので、違うやり方を考えてみる。

  • 案1 url をキーに要素を検索する ← url が被る可能性があるのでアウト
  • 案2 ページ内の要素をユニークに判別できるものを利用する(あれば)

という訳で、ユニークな識別子を探してみた。
index(subject) - jQuery 日本語リファレンス

これならページ内に複数あっても、一意に判別できるようだ。

考え方としては、ページ内の全aタグに対して、ターゲットが何番目なのかが知りたいわけだ。
するとこうなるか

var hoge = $('a').index(target)

で、逆にインデックスから要素にアクセスするのが eq
eq(index) - jQuery 日本語リファレンス

コードはこうなる

$('a').eq(index).attr('href')
$('a').eq(index).text()

あとはこれを実行すれば、それぞれ戻り値として取得できる。


感想

こうやって書くとさっくりできたような気もするが、割と試行錯誤で大変だった。
でも、ちょっと javascript できる気になれました。