JavaScript Web API: обрабатывать длинные TouchEvent, сохраняя поведение по умолчанию в браузере? - PullRequest
1 голос
/ 09 марта 2020

В дополнение к MouseEvent s я хотел бы использовать «длинный» TouchEvent одного пальца / цифры / ввода для моего приложения (изменить режим, например, чтобы начать рисовать или выбрать элементы для управления), сохраняя при этом все действия по умолчанию, такие как нажатие / нажатие, прокрутка / перемещение и удержание для контекстного меню или удержание для выбора.

Другими словами:

  1. короткое касание (касание) должно быть аналогично обычному щелчку мыши (обычно эмулируется браузером)
  2. (короткое) касание и перемещение (пролистывание) должны вызывать обычную прокрутку
  3. a "дольше «касание должно быть аналогично нажатию и удержанию мыши
  4. последующие события перемещения не должны вызывать прокрутку, а обрабатываются приложением
  5. длительное касание без перемещения должно вызывать нормальную вторичную функцию (выберите , context-menu)
  6. Сжатие и другие мультитач-жесты должны использовать обработчики по умолчанию (на данный момент)

Нет события удержания для выбора или аналогичного события для моего знания, поэтому я пытаюсь реализовать это сам.

Обнаружить «длинное» касание перед перетаскиванием довольно просто (setTimeout(), например, Как определить долгое касание с помощью javascript для android и iphone? ), однако, начальный touchstart, похоже, уже запускает обработчики событий по умолчанию, вызывая

  • без прокрутки (предназначено)
    • Chrome вкл Windows
    • Chrome на Android
  • прокрутка
    • Safari на iOS (iPhone)
    • Firefox на Windows и Android
  • второстепенные функции
    • выберите (не предназначен, если происходит перемещение)
      • Safari на iOS (iPhone)
    • лупа (не предназначена для перемещения)
      • Safari на iOS (iPhone)
    • контекстное меню (предназначено, когда не происходит перемещения)
    • Chrome вкл. Windows: по назначению (очень длинное касание, без движения)
    • Firefox вкл. Windows: по назначению (очень длинное касание, без движения)
    • Chrome на Android: нет
    • Firefox на Android: none

на реальных устройствах, несмотря на preventDefault() и stopPropagation() вызовы от touchmove.

  • уже есть "лучший" способ ( событие, о котором я не знаю)?
  • возможно ли задним числом повлиять на эти события / обработчики (отменить / отменить события?)?
  • есть ли способ определить действия по умолчанию ( выберите, контекстное меню) и соответствующий тайм-аут (зависит от реализации браузера / ОС)?

или

  • Придется ли мне самому заново реализовывать обработчики очень низкого уровня а затем создавать и генерировать необходимые события (с учетом различных реализаций браузера)?

Вот предварительный фрагмент для тестирования (не стесняйтесь улучшать / расширять):

let t = document.getElementById("t");
t.innerHTML += navigator.userAgent + '<br/>'; 

// timer
var timerid;
var touchduration = 500;
var longtouch = false;
function lt(e){
  timerid = undefined;
  longtouch = true;
  e.preventDefault();
  e.stopPropagation();
  ls("LONG");
}
function ct(){if (timerid)window.clearTimeout(timer); timerid = undefined;}

function ls(s){
  t.innerHTML += i + ' ' + s + '<br/>';  
  t.scrollTop = t.scrollHeight;
}

// log event
let i = 0;
let o;
function le(e){
  if (e.type!=o){
    ls( e.type + (longtouch?' LONG':'') );
    o = e.type;
    }
  i++;
}

// mouse
t.addEventListener("mouseenter",  e=>{le(e);});
t.addEventListener("mousedown",   e=>{le(e);});
t.addEventListener("mouseup",     e=>{le(e);});
t.addEventListener("mousemove",   e=>{le(e);});
t.addEventListener("mouseout",    e=>{le(e);});
t.addEventListener("mouseleave",  e=>{le(e);});

t.addEventListener("click",  			e=>{le(e);});
t.addEventListener("dblclick",  	e=>{le(e);});
t.addEventListener("auxclick",  	e=>{le(e);});

// wheel
t.addEventListener("wheel",       e=>{le(e);});

// touch
t.addEventListener("touchstart",  e=>{le(e); 
  timerid = window.setTimeout(lt, 500, e);
  });
t.addEventListener("touchend",    e=>{le(e);
  ct();
  longtouch = false;
  });
t.addEventListener("touchmove",   e=>{le(e);
  ct();
  if (longtouch) {
    e.preventDefault();
    e.stopPropagation();
    //e.stopImmediatePropagation();
    }
  });
t.addEventListener("touchcancel", e=>{le(e);});


t.addEventListener("drag",        e=>{le(e);});

t.addEventListener("scroll",      e=>{le(e);});

t.addEventListener("contextmenu", e=>{le(e);});
t.addEventListener("select",      e=>{le(e);});
<div id="t" style="height:10em; max-height:100%; overflow-y:scroll; border: 1px solid green;"/>
...