どうもosuga-hです。 イベントハンドラの引数のtargetプロパティには必ずHTML要素が代入されるように実装されていることが多いですが、 iPhone4ではTextNodeも対象となるように実装されているようです。 おとなしくevent.currentTarget使ってればこんなことにはならないんですけど、予想外の挙動だったことは間違いないんで、紹介したいと思います。

問題となったコード断片

 1 <div id="menu1">menu1</div>
 2 <div id="menu2">menu2</div>
 3 <script type="text/javascript">
 4 var menu1 = document.getElementById( "menu1" ),
 5     menu2 = document.getElementById( "menu2" );
 6 
 7 menu1.addEventListener( "touchstart" , onTouchStart , false );
 8 menu2.addEventListener( "touchstart" , onTouchStart , false );
 9 
10 function onTouchStart ( event ){
11     menu1.removeEventListener( "touchstart" , onTouchStart , false );
12     menu2.removeEventListener( "touchstart" , onTouchStart , false );
13 
14     var target = event.target ;
15     if( target == menu1 ){
16         //menu1の処理
17     }else{
18         //menu2の処理
19     }
20     //画面が遷移する
21 }
22 </script>
#menu1も#menu2も中にテキスト以外の要素を持っていないから、event.targetはいつも同じになるだろうという予想の元にこのようなコードを書いていました。 ところがiPhone4でmenu1をクリックしたにもかかわらずmenu2の処理が走るという問題に遭遇したのです。

原因

原因は冒頭でも述べましたがiPhone4の場合テキストを"タッチ"するとtargetにTextNodeが渡されてきます。 このため#menu1をクリックしたとしても target != menu1 となり、menu2の処理が走っていました。 以下は検証用途のコードです。
 1 <div id="elem1"> |←壁の向こうと、こっち側でevent.targetの内容がちがう→|</div>
 2 
 3 <style type="text/css">
 4 #elem1 {
 5     padding:20px;
 6     text-align:center;
 7     border:1px solid #000;
 8 }
 9 </style>
10 
11 <script type="text/javascript">
12     document.getElementById( "elem1" ).addEventListener( "touchstart" , function ( event ){
13        alert( event.target );
14     } , false );
15 </script>
テキストの上をタッチすると 余白をタッチすると touchstart , touchmove , touchend全てでTextNodeが渡ってきました。 んーclickイベントでは渡ってこないから、たぶんバグだけどW3C的には問題ないと言えば言えないこともない実装・・・。

解決

このケースでは問題を回避するのは簡単です、EventオブジェクトのcurrentTargetプロパティを使います。 currentTargetにはaddEventListnerした要素が渡ってきます。
 1 <div id="menu1">menu1</div>
 2 <div id="menu2">menu2</div>
 3 <script type="text/javascript">
 4 var menu1 = document.getElementById( "menu1" ),
 5     menu2 = document.getElementById( "menu2" );
 6 
 7 menu1.addEventListener( "touchstart" , onTouchStart , false );
 8 menu2.addEventListener( "touchstart" , onTouchStart , false );
 9 
10 function onTouchStart ( event ){
11     menu1.removeEventListener( "touchstart" , onTouchStart , false );
12     menu2.removeEventListener( "touchstart" , onTouchStart , false );
13 
14     var target = event.currentTarget;
15     if( target == menu1 ){
16         //menu1の処理
17     }else if( target == menu2 ){
18         //menu2の処理
19     }else{
20         //例外処理
21     }
22     //画面が遷移する
23 }
24 </script>
ついでにもう少し安全なコードに書き換えました。

まとめ

iPhoneではevent.targetにTextNodeも渡される。 イベントハンドラでaddEventListenerした対象かどうか調べたいときはevent.currentTargetを使ったほうが安全。 event.targetやevent.currentTargetについてはこちらの説明も合わせて御覧ください。 Document Object Model Events | Event interface