babu_babu_babooのごみ箱

2012-10-08

iOS6 にしたら、addEventListener の第2引数にしていしてた、handleEvent メソッド をもつオブジェクトが使えなくなった?

| 09:30

addEventListener の第2引数には、

オブジェクト型の handleEvent メソッドは使えるけど、

関数型の handleEvent メソッドは、使えない。


iOS6 touchendイベントが拾えない。しかも他でも報告があるのでバグっぽい。

HTML要素に対してクリックイベントでイベントを呼び出すことがこれまでもできなかった。

touchend イベントが起こらず、今のところ touchstart が発生したら強制的にマウスのクリックイベントを発火させている


追記

最小コードだと、touchend を拾えている。なぜ?

だけれども、指を離さなくても拾えてるときがある。なぜ?

使い物にならない?


更に追記

touchend イベントを起こすために、まず二本指で触れ、それを時間差で放す。

今はそれぐらいしか対処できない。

<!DOCTYPE html><title></title><meta charset="UTF-8"><body>
<h1>Test</h1>
<script>
document.addEventListener (
  'touchend',
  { handleEvent: function (event) { alert ('ObjectBase:' + event.type); } },
  false
);
</script>

if (/iPhone|iPad|iPod/.test (navigator.userAgent)) (function () {

  var RANGE = 10;
  var STATE = false;
  var POINT = { x0: null, y0: null, x1: null, y1: null };

  function FireMouseEvent (
    target,
    type, canBubble, cancelable, view,
    detail, screenX, screenY, clientX, clientY, 
    ctrlKey, altKey, shiftKey, metaKey, button,
    relatedTarget) {

    var doc = target.ownerDocument;
    var event = doc.createEvent ('MouseEvents');

    event.initMouseEvent (
      type       || 'click',
      canBubble  || true,
      cancelable || true,
      view       || doc.defaultView,
      detail     || 0,
      screenX    || 0,
      screenY    || 0,
      clientX    || 0,
      clientY    || 0, 
      ctrlKey    || false,
      altKey     || false,
      shiftKey   || false,
      metaKey    || false,
      button     || false,
      relatedTarget || null
    );
    target.dispatchEvent (event);
  }

  
  function clickHandleEventEmulator (event) {
    var touch = event.touches[0];
    var e = touch.target;
    var px = touch.pageX;
    var py = touch.pageY;
    switch (event.type) {
    case 'touchstart' :
      switch (e.tagName) {
      case 'INPUT' : case 'SELECT' : case 'TEXTAREA' :
        return;
      default :
        FireMouseEvent (e, 'click');
        POINT.x0 = px - RANGE;
        POINT.y0 = py - RANGE;
        POINT.x1 = px + RANGE;
        POINT.y1 = py + RANGE;
        STATE = true;
      }
      break;
    
    case 'touchmove' :
      if (STATE) {
        STATE = ! (px < POINT.x0 || POINT.x1 < px || py < POINT.y0 || POINT.y1 < py);
      }
      break;
    
    case 'touchend' :
      if (STATE) {
        FireMouseEvent (e, 'click');
        STATE = false;
      }
      break;
    };
  }
  
  function init () {
    var d = document;
    d.addEventListener ('touchstart', clickHandleEventEmulator, false);
    d.addEventListener ('touchmove',  clickHandleEventEmulator, false);
    d.addEventListener ('touchend',   clickHandleEventEmulator, false);
  }
  
  init ();
})();

上のコードの余計なものを省いた

if (/iPhone|iPad|iPod/.test (navigator.userAgent)) (function () {

  function FireMouseEvent (
    target,
    type, canBubble, cancelable, view,
    detail, screenX, screenY, clientX, clientY, 
    ctrlKey, altKey, shiftKey, metaKey, button,
    relatedTarget) {

    var doc = target.ownerDocument;
    var event = doc.createEvent ('MouseEvents');

    event.initMouseEvent (
      type       || 'click',
      canBubble  || true,
      cancelable || true,
      view       || doc.defaultView,
      detail     || 0,
      screenX    || 0,
      screenY    || 0,
      clientX    || 0,
      clientY    || 0, 
      ctrlKey    || false,
      altKey     || false,
      shiftKey   || false,
      metaKey    || false,
      button     || false,
      relatedTarget || null
    );
    target.dispatchEvent (event);
  }

  
  function clickHandleEventEmulator (event) {
    var touch = event.touches[0];
    var e = touch.target;

    switch (event.type) {
    case 'touchstart' :
      switch (e.tagName) {
      case 'INPUT' : case 'SELECT' : case 'TEXTAREA' :
        return;
      default :
        FireMouseEvent (e, 'click');
      }
      break;
    };
  }
  
  function init () {
    var d = document;
    d.addEventListener ('touchstart', clickHandleEventEmulator, false);
  }
  
  init ();
})();

think49think49 2012/10/08 15:29 つまり、下記コードが動かないということでしょうか。

function listener () { ; }
listener.handleEvent = function handleEvent (event){ alert(event.type); };
document.addEventListener('click', listener, false);

babu_babu_baboobabu_babu_baboo 2012/10/08 16:47 おっ!あっ! お久しぶりです

そうなんです。詳しくはまだ調べてないのですが、司会をするための webapl が動かなく、今夜から徹夜かも?

babu_babu_baboobabu_babu_baboo 2012/10/09 08:50 結局、睡魔には勝てなかった。
反応するのは、listenerObj のほうだけ。
あ〜書き直すのが面倒です。

var listenerObj = { };
listenerObj.handleEvent = function (event) { alert ('ObjectBase:' + event.type); };
document.addEventListener('touchstart', listenerObj, false);

var listenerFunc = function () {;};
listenerFunc.handleEvent = function (event) { alert ('FunctionBase:' + event.type); };
document.addEventListener('touchstart', listenerFunc, false);