webentwicklung-frage-antwort-db.com.de

Bevorzugte Alternative zu OnMouseOver für Berührung

Gibt es eine bevorzugte Alternative oder bewährte Methode für die Handhabung von OnMouseOver-JavaScript-Ereignissen auf Touch-Geräten? Alles, was ich denken kann, ist, alle Ereignisse in OnMouseClick umzuwandeln. Leider werden die Unterschiede zwischen Ereignissen, die durch das Bewegen des Cursors ausgelöst werden, und Ereignissen, die durch Klicken mit dem Cursor ausgelöst werden, durcheinander gebracht. 

Gibt es Alternativen oder Umgehungen, die für die UX einer Webseite weniger störend sind und von beiden Mausgeräten und Touchgeräten verwendet werden?

39
Daniel Nill

Gibt es eine bevorzugte Alternative oder bewährte Methode für die Handhabung von OnMouseOver-JavaScript-Ereignissen auf Touch-Geräten?

Die kurze Antwort lautet nein.

Gerätespezifische Ereignisse haben keine 1: 1-Zuordnung zu Ereignissen von anderen Geräten. Es gibt kein richtiges Äquivalent zum „Schweben“ bei der Verwendung von Touch.

Mausereignisse (mouseover, mouseout, mousedown, mouseup, mousemove usw.) sind für das Mauseingabegerät spezifisch. Die Tastatur verfügt über die Tasten keydown, keypress und keyup. Berühren Sie touchstart, touchmove, touchend und touchcancel. Das Webkit auf dem iPhone/iPad/etc enthält zusätzliche gesture start/move/end -Ereignisse, die Apple-spezifisch sind.

Generische Ereignisse auf höherer Ebene wie focus, blur, click, submit usw. können durch eines dieser Ereignisse ausgelöst werden. Ein click -Ereignis kann zum Beispiel mit einem Maus-, Tast- oder Tastaturereignis ausgelöst werden. (click, btw, ist ein Ereignis mit einem unangemessenen Namen, der eigentlich action heißen sollte, aber aufgrund seiner Maus-Historie immer noch click heißt).

Der bevorzugte Ansatz (oder "One Web") besteht in der Verwendung der Mausereignisse für mausspezifische Dinge, bei denen Sie diese nicht vermeiden können, und die allgemeinen Ereignisse für alles andere.

Abhängig vom WebKit-Build und den zum Erstellen verwendeten Flags können Sie einige Mausereignisse auf einige Touch-Schnittstellen in einige Sonderfälle auslösen, aber Sie möchten Ihre Benutzeroberfläche wirklich nicht erstellen Dies liegt daran, dass der einzige Grund für diese Fälle darin besteht, Mobile-Webkit auf dem Markt Fuß zu fassen.

Berührungsereignisse sind auch über Plattformen hinweg inkonsistent. Werfen Sie einen Blick auf die Arbeit von ppk, wenn Sie etwas für Handys/Berührungen tun möchten, http://quirksmode.org/mobile/tableTouch.html .

34
Michiel Kalkman

Die Onmouseover/Onmouseout-JavaScript-Events würden in Touchenter/Touchleave-Touch-Events übersetzt. Das Problem ist, dass diese Events erst in Browsern implementiert werden (sie sind Teil eines W3C Draft ). Derzeit wird nur Firefox unterstützt , wenn Sie also Webkit verwenden, müssen Sie darauf warten oder Ihre Onmouseover-Funktion mithilfe des touchmove-Ereignisses implementieren und die Koordinaten prüfen, um zu sehen, ob sie mit den Koordinaten Ihres HTML-Elements überlappen.

6
Nelson

Abhängig von Ihren Anforderungen und den angesprochenen Benutzern sind Sie möglicherweise an den Touch-JS-APIs (zumindest) für mobile Safari und Chrome interessiert. Check http://backtothecode.blogspot.com/2009/10/javascript-touch-and-gesture-events.html , für eine schnelle (vielleicht etwas veraltete) Einführung. Ich habe diese nicht wirklich ausgiebig genutzt (z. B. nur für das iPhone), aber ich war mit den bisherigen Ergebnissen sehr zufrieden.

3

Leider weiß ich nicht über Best Practices oder eine Preferred - Alternative zu onmouseover auf Touch-Geräten, aber da ich auf dieselbe Frage stieß, entwickelte ich diese VanillaJS-Lösung, in der ich die Millisekunden zwischen onmouseenter und onclick zähle Um zwischen Desktop-Klick und Mobile-Klick zu unterscheiden.

Bei der Untersuchung der beiden Ereignisse in den Umgebungen mit Desktop und in mobilen Umgebungen entdeckte ich, dass eine mobile Berührung beide Ereignisse sofort (beide innerhalb von null Millisekunden) auslöst, im Gegensatz zur kleinen Desktop-Verzögerung von einigen Dutzend Millisekunden, abhängig vom Auslöser des Benutzers -Glück.

;(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's 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's 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>

(… Oder alternativ als Geige )

Hier ist eine weitere Geige , um speziell den zeitlichen Unterschied zwischen Desktop- und mobilen Umgebungen zu zeigen.

1
WoodrowShigeru

Ich glaube, ich habe es geschafft, eine gute Simulation zu erstellen (zumindest für einen bestimmten Ereignishandler, den ich simulieren wollte), indem ich den Ereignishandler 'touchmove' kombinierte und die Methode elementFromPoint () mit den Koordinaten (die in den clientX/clientY-Eigenschaften des gespeichert sind) aufruft Objekt) des relevanten Touch-Objekts im Ereignis (ich habe e.touches [0] verwendet). 

Eine ausführlichere Antwort finden Sie in meiner Antwort zu diesem spezifischen Anwendungsfall dieses Benutzers (Füllen der Zellen einer Tabelle) basierend auf einer Lösung für mein eigenes Problem (Aktivieren der Kontrollkästchen-Status) hier: https://stackoverflow.com/a/ 31711040/1941313 .

Lesen Sie alternativ den vollständigen Bericht, den ich über das Finden des Schreibereignishandlerdesigns geschrieben habe, einschließlich der Quellen für meine Ergebnisse in der folgenden Gist: https://Gist.github.com/VehpuS/6fd5dca2ea8cd0eb0471

(Ich hätte sie in stackoverflow gepostet, aber meine rep ist im Moment zu niedrig, daher kann ich nur zwei Links angeben: P)

Hoffe das hilft!