Подтвердить что ты не робот

Предпочтительная альтернатива OnMouseOver для прикосновения

Есть ли предпочтительная альтернатива или лучшая практика для обработки событий javascript OnMouseOver на сенсорных устройствах? Все, что я могу думать, это преобразовать все события в OnMouseClick. К сожалению, это мешает различиям между событиями, вызванными наведением курсора и событиями, вызванными щелчком курсора.

Существуют ли какие-либо альтернативы или обходные пути, которые менее разрушительны для UX веб-страницы, которая будет использоваться как с устройствами мыши, так и с сенсорными устройствами?

4b9b3361

Ответ 1

Есть ли предпочтительная альтернатива или лучшая практика для обработки событий javascript OnMouseOver на сенсорных устройствах?

Короткий ответ - нет.

События, специфичные для устройства, не имеют сопоставления 1:1 с событиями других устройств. При использовании Touch нет соответствующего эквивалента "зависания".

События мыши (mouseover, mouseout, mousedown, mouseup, mousemove и т.д.) относятся к устройству ввода мыши. Клавиатура имеет keydown, keypress и keyup. Touch имеет touchstart, touchmove, touchhend и touchcancel. Webkit на iPhone/iPad/etc имеет дополнительные события запуска/перемещения/завершения жестов, которые специфичны для Apple.

Одним из этих событий может быть вызван более высокий уровень, общие события, такие как фокус, размытие, щелчок, отправка и т.д. Например, событие клика может быть запущено с помощью мыши, касания или события клавиатуры. (click, btw, является событием с неправильным именем, которое должно быть более правильно вызвано действием, но из-за его истории мыши по-прежнему называется click).

Предпочтительный (или "один Интернет" ) подход использует события мыши для конкретных вещей мыши, где вы не можете их избежать и придерживаться общих событий для всего остального.

В зависимости от сборки WebKit и флагов, используемых для ее создания, вы можете запускать некоторые события мыши на некоторых сенсорных интерфейсах в некоторых особых случаях, но вы действительно не хотите создавать свой интерфейс, потому что единственная причина, по которой эти случаи существуют это позволить мобильному-Webkit получить тягу на рынке.

События Touch также несовместимы между платформами. Взгляните на работу ppk для какой-либо ссылки, если вы делаете какие-либо мобильные/сенсорные вещи, http://quirksmode.org/mobile/tableTouch.html

Ответ 2

События javascript onmouseover/onmouseout будут переведены на сенсорные события touchhenter/touchleave, проблема в том, что эти события только начинают реализовываться в браузерах (они являются частью проекта W3C), в настоящее время только firefox поддерживает его, поэтому, если вы используете webkit, вам придется подождать или реализовать свою функцию onmouseover с помощью события touchmove и глядя на координаты и посмотреть, пересекаются ли они с координатами вашего элемента html.

Ответ 3

В зависимости от ваших требований и целевых пользователей вы можете быть заинтересованы в сенсорных JS API, доступных (по крайней мере) на мобильных Safari и Chrome. Проверьте http://backtothecode.blogspot.com/2009/10/javascript-touch-and-gesture-events.html для быстрого (возможно, немного устаревшего) введения. Я действительно не использовал их широко (только для таргетинга на iPhone, например), но я был очень доволен результатами, которые я получил до сих пор.

Ответ 4

Мне кажется, мне удалось создать хорошую симуляцию (по крайней мере для конкретного обработчика событий, которую я хотел смоделировать), объединив обработчик события touchmove и вызвав метод elementFromPoint(), используя координаты (сохраненные в clientX/clientY свойства объекта) соответствующего объекта Touch в событии (я использовал e.touches [0]).

Более подробный ответ см. в моем ответе на этот конкретный случай использования пользователя (заполнение ячеек таблицы) на основе решения моей собственной проблемы (переключение состояний флажка) здесь: fooobar.com/questions/149884/....

В качестве альтернативы, прочитайте полный отчет, который я написал о поиске дизайна обработчика событий записи, включая источники для моих результатов в следующем виде: https://gist.github.com/VehpuS/6fd5dca2ea8cd0eb0471

(я бы разместил их в stackoverflow, но мой rep был слишком низким на данный момент, поэтому я могу предоставить только две ссылки: P)

Надеюсь, это поможет!

Ответ 5

К сожалению, я не знаю о передовых методах или предпочтительной альтернативе onmouseover на сенсорных устройствах, но, столкнувшись с тем же вопросом, я закончил разработку этого решения vanillaJS, в котором я считаю миллисекунды между onmouseenter и onclick, и поэтому могу различать настольные компьютеры. -кликинг и мобильный-клик.

Изучив два события в настольных и мобильных средах, я обнаружил, что мобильное прикосновение изначально запускает оба события мгновенно (оба в течение нуля миллисекунд), в отличие от небольшой задержки рабочего стола в несколько десятков миллисекунд, в зависимости от пользовательского триггера. -счастье.

;(function(){
	let
		hover_on_mobile = {
			timer: 0,
      // I don't trust the timer with this,
      // so I'm counting myself:
			milliseconds: 0,
      // also cover the case of the user
      // mouseentering, reading or otherwise
      // waiting, and clicking *then*.
			is_counting: false,
		},
    item = document.querySelector('.mobile-hoverable')
	;
	hover_on_mobile.reset = function(){
		clearInterval(hover_on_mobile.timer);
		hover_on_mobile.milliseconds = 0;
		hover_on_mobile.is_counting = false;
	};

	// hover.
	item.onmouseenter = function(){

		// preparation for onclick touch-click detection.
		hover_on_mobile.is_counting = true;
		// count the milliseconds starting on each 
    // mouseenter anew.
		hover_on_mobile.timer = window.setInterval(function() {
			// we only need the first few milliseconds for
      // our touch-click detection.
			if (hover_on_mobile.milliseconds > 50) {
				hover_on_mobile.reset();

			} else {
				hover_on_mobile.milliseconds++;
			}
		}, 1);

		hover_behavior();
	};

	// click.
	item.onclick = function(ev){
		let
			condition1 = hover_on_mobile.milliseconds < 10,
			condition2 = hover_on_mobile.is_counting
		;
		console.log('clicked', {
			condition1: condition1,
			condition2: condition2,
			timer: hover_on_mobile.timer,
      milliseconds: hover_on_mobile.milliseconds,
			is_counting: hover_on_mobile.is_counting,
		});
		// touch-click detection.
		if (condition1 && condition2) {
			// don't do anything; let the onmouseenter 
      // do the hover routine unhinderedly.
      //
			// if this was an onclick event on an ‹a› tag, 
      // the ev.preventDefault(); call would go here.
      
		} else {
			click_behavior();
		}
		hover_on_mobile.reset();
	};
  
  
  // ----------------------------------------
  // fiddle-specfic.

	// reset indicator, not hover_on_mobile.
	item.onmouseout = reset_indicator;

	function click_behavior() {
		document.querySelector('#indicator .click-text').innerText = 'clicked';
	}

	function hover_behavior() {
		document.querySelector('#indicator .hover-text').innerText = 'hovered';
	}

	function reset_indicator() {
		document.querySelector('#indicator .hover-text').innerText = '-';
		document.querySelector('#indicator .click-text').innerText = '-';
	}

	document.querySelector('#indicator .reset').onclick = reset_indicator;

})();
h1 {
  font-size: 20px;
  line-height: 26px;
}

#indicator {
  margin-top: 15px;
  padding: 20px;
  background-color: #ddd;
}

.mobile-hoverable {
  cursor: pointer;
  background-color: antiquewhite;
  border: 1px outset blanchedalmond;
  border-radius: 4px;
  padding: 10px;
}

.notes {
  font-style: italic;
  font-size: 14px;
}
<div class="root">
  <h1>Imagine you wanted mobile users to click once in order to simulate a desktop-hover and twice for a desktop-click</h1>
  
  <div class="mobile-hoverable">Hover me, click me, compare with mobile-touch device mode.</div>
  
  <div id="indicator">
    <button class="reset">Reset</button>
    <span class="hover-text">-</span>
    <span class="click-text">-</span>
  </div>
  
  <ul class="notes">
    <li>Don't forget to reload the page after changing the mode, for optimal testing evaluation.</li>
    <li>Click event console.logs hover_on_mobile object.</li>
    <li>The fiddle CSS is irrelevant for this feature.</li>
    <li>Relevant JavaScript is bundled together; irrelevant JavaScript at the end.</li>
    <li>Didn't test browser compatibility specifically for this fiddle but the feature works in Chrome, Firefox, Safari, IE10+.</li>
    <li>Subsequent clicks without onmouseout will only fire the click event, in both environments.</li>
  </ul>
</div>