it-swarm.com.de

Feststellen, dass der Browser keine Maus hat und nur berührungslos ist

Ich entwickle eine Web-App (keine Website mit interessanten Textseiten) mit einer ganz anderen Oberfläche für die Berührung (Ihr Finger verbirgt den Bildschirm, wenn Sie klicken) und die Maus (hängt stark von der Hover-Vorschau ab) dass mein Benutzer keine Maus hat, um ihm die richtige Schnittstelle zu präsentieren? Ich habe vor, einen Schalter für Menschen mit Maus und Berührung zu lassen (wie bei einigen Notebooks). 

Die Touch-Event-Funktion im Browser bedeutet nicht, dass der Benutzer ein Touch-Gerät verwendet (z. B. schneidet Modernizr es nicht ab). Der Code, der die Frage richtig beantwortet, sollte false zurückgeben, wenn das Gerät über eine Maus verfügt, andernfalls true. Bei Geräten mit Maus und Berührung sollte "false" zurückgegeben werden (nicht nur bei Berührung).

Als Randbemerkung ist mein Touch-Interface möglicherweise auch für reine Tastaturgeräte geeignet, daher ist es eher das Fehlen einer Maus, die ich erkennen möchte.

Um die Notwendigkeit klarer zu machen, ist hier die API, die ich implementieren möchte:

// Level 1


// The current answers provide a way to do that.
hasTouch();

// Returns true if a mouse is expected.
// Note: as explained by the OP, this is not !hasTouch()
// I don't think we have this in the answers already, that why I offer a bounty
hasMouse();

// Level 2 (I don't think it's possible, but maybe I'm wrong, so why not asking)

// callback is called when the result of "hasTouch()" changes.
listenHasTouchChanges(callback);

// callback is called when the result of "hasMouse()" changes.
listenHasMouseChanges(callback);
135
nraynaud

Das Hauptproblem ist, dass Sie die folgenden unterschiedlichen Geräteklassen/Anwendungsfälle haben:

  1. Maus und Tastatur (Desktop)
  2. Nur berühren (Telefon/Tablet)
  3. Maus, Tastatur und Touch (Touch-Laptops)
  4. Touch und Tastatur (Bluetooth-Tastatur auf dem Tablet)
  5. Nur Maus (deaktivierte Benutzer-/Browsereinstellung)
  6. Nur Tastatur (deaktivierte Benutzer-/Browsereinstellung)
  7. Berührung und Maus (z. B. Hover-Ereignisse vom Galaxy Note 2-Stift)

Schlimmer ist, dass man von einigen dieser Klassen zu anderen wechseln kann (Stecker in einer Maus, verbindet sich mit der Tastatur), oder ein Benutzer kann auf einem normalen Laptop AUSSEHEN, bis er den Bildschirm berührt.

Sie haben zu Recht die Annahme, dass das Vorhandensein von Ereigniskonstruktoren im Browser kein guter Weg ist, um vorwärts zu kommen (und etwas inkonsistent ist). Darüber hinaus ist die Verwendung von Ereignissen an sich kein vollständiger Beweis, es sei denn, Sie verfolgen ein ganz bestimmtes Ereignis oder versuchen nur, einige Klassen oben auszuschließen.

Angenommen, Sie haben entdeckt, dass ein Benutzer eine echte Mausemove ausgegeben hat (nicht die falsche von Touch-Ereignissen, siehe http://www.html5rocks.com/de/mobile/touchandmouse/ ).

Dann was?

Sie aktivieren Hover-Stile? Sie fügen weitere Schaltflächen hinzu?

So oder so erhöhen Sie die Zeit bis zum Glas, weil Sie warten müssen, bis ein Ereignis ausgelöst wird.

Aber was passiert, wenn sich Ihr edler Benutzer entscheidet, seine Maus vom Computer zu trennen und die volle Berührung zu erreichen? Warten Sie darauf, dass er Ihr jetzt vollgestopftes Interface berührt, und ändern Sie es gleich, nachdem er sich die Mühe gemacht hat, Ihre nun überfüllte Benutzeroberfläche zu bestimmen?

In Aufzählungsform unter Verwendung von stucox unter https://github.com/Modernizr/Modernizr/issues/869#issuecomment-15264101

  • Wir möchten die Anwesenheit einer Maus feststellen
  • Ae kann wahrscheinlich nicht erkennen, bevor ein Ereignis ausgelöst wird
  • Was wir als solches erkennen, ist, wenn in dieser Sitzung eine Maus verwendet wurde - sie wird nicht sofort vom Laden der Seite übernommen
  • Wir können wahrscheinlich auch nicht erkennen, dass es keine Maus gibt - sie wäre undefiniert, bis sie wahr ist (ich denke, das macht mehr Sinn als das Einstellen
  • Und wir können wahrscheinlich nicht erkennen, ob eine Maus während der Sitzung getrennt ist. Dies ist nicht zu unterscheiden von dem Benutzer, der nur seine .__ aufgibt. Maus

Nebenbei bemerkt: Der Browser weiß, wann ein Benutzer eine Maus an eine Tastatur anschließt/eine Verbindung mit einer Tastatur herstellt, diese aber nicht JavaScript ausliefert. Dang!

Dies sollte Sie zu folgendem führen:

Das Nachverfolgen der aktuellen Fähigkeiten eines Benutzers ist komplex, unzuverlässig und von zweifelhaftem Wert.

Die Idee der progressiven Verbesserung trifft hier jedoch durchaus zu. Erstellen Sie ein Erlebnis, das unabhängig vom Kontext des Benutzers reibungslos funktioniert. Nehmen Sie dann basierend auf Browserfunktionen/Medienabfragen Annahmen vor, um Funktionen hinzuzufügen, die im angenommenen Kontext relativ sind. Die Anwesenheit einer Maus ist nur eine der vielen Möglichkeiten, auf denen verschiedene Benutzer auf verschiedenen Geräten Ihre Website erleben. Erstellen Sie etwas mit Verdienst im Kernel und sorgen Sie sich nicht zu sehr darum, wie die Leute auf die Schaltflächen klicken.

56
Wyatt

Wie wäre es mit einem Mousemove-Ereignis auf dem Dokument? Bis Sie dieses Ereignis hören, gehen Sie davon aus, dass es sich bei dem Gerät nur um Berührung oder um Tastatur handelt.

var mouseDetected = false;
function onMouseMove(e) {
  unlisten('mousemove', onMouseMove, false);
  mouseDetected = true;
  // initializeMouseBehavior();
}
listen('mousemove', onMouseMove, false);

(Wo listen und unlisten nach Bedarf an addEventListener oder attachEvent delegieren.)

Hoffentlich würde dies nicht zu viel visuellen Ruck führen, es wäre scheiße, wenn Sie umfangreiche Neugestaltungen basierend auf dem Modus benötigen ...

56
Dan

@ Wyatt's Antwort ist großartig und gibt uns viel zu denken.

In meinem Fall habe ich mich für die erste Interaktion entschieden, um erst dann ein Verhalten festzulegen. Selbst wenn der Benutzer eine Maus hat, werde ich als Berührungsgerät behandelt, wenn die erste Interaktion eine Berührung war. 

Berücksichtigt die vorgegebene Reihenfolge, in der Ereignisse verarbeitet werden :

  1. touchstart
  2. touchmove
  3. touchend
  4. mouseover
  5. mousemove
  6. maus nach unten
  7. mouseup
  8. klicken

Wir können davon ausgehen, dass das Mausereignis, wenn es vor dem Berühren ausgelöst wird, ein echtes Mausereignis und kein emuliertes ist. Beispiel (mit jQuery):

$(document).ready(function() {
    var $body = $('body');
    var detectMouse = function(e){
        if (e.type === 'mousedown') {
            alert('Mouse interaction!');
        }
        else if (e.type === 'touchstart') {
            alert('Touch interaction!');
        }
        // remove event bindings, so it only runs once
        $body.off('mousedown touchstart', detectMouse);
    }
    // attach both events to body
    $body.on('mousedown touchstart', detectMouse);
});

Das hat bei mir funktioniert

23
Hugo Silva

Es kann nur festgestellt werden, ob ein Browser fähig ist. Es gibt keine Möglichkeit festzustellen, ob tatsächlich ein Touchscreen oder eine Maus angeschlossen ist.

Man kann die Verwendung jedoch priorisieren, indem man das Berührungsereignis anstelle des Mausereignisses hört, wenn die Berührungsfähigkeit erkannt wird.

So erkennen Sie die berührungsübergreifende Berührungsfähigkeit:

function hasTouch() {
    return (('ontouchstart' in window) ||       // html5 browsers
            (navigator.maxTouchPoints > 0) ||   // future IE
            (navigator.msMaxTouchPoints > 0));  // current IE10
}

Dann kann man dies verwenden, um zu überprüfen:

if (!hasTouch()) alert('Sorry, need touch!);

oder wählen Sie das Ereignis aus, das Sie hören möchten:

var eventName = hasTouch() ? 'touchend' : 'click';
someElement.addEventListener(eventName , handlerFunction, false);

oder verwenden Sie getrennte Ansätze für Berührung vs. Nichtberührung:

if (hasTouch() === true) {
    someElement.addEventListener('touchend' , touchHandler, false);

} else {
    someElement.addEventListener('click' , mouseHandler, false);

}
function touchHandler(e) {
    /// stop event somehow
    e.stopPropagation();
    e.preventDefault();
    window.event.cancelBubble = true;
    // ...
    return false; // :-)
}
function mouseHandler(e) {
    // sorry, touch only - or - do something useful and non-restrictive for user
}

Bei der Maus kann nur festgestellt werden, ob die Maus verwendet wird, nicht ob sie existiert oder nicht. Man kann ein globales Flag einrichten, um anzuzeigen, dass die Maus bei der Verwendung erkannt wurde (ähnlich einer vorhandenen Antwort, jedoch etwas vereinfacht):

var hasMouse = false;

window.onmousemove = function() {
    hasMouse = true;
}

(man kann nicht mouseup oder mousedown einschließen, da diese Ereignisse auch durch Berührung ausgelöst werden können)

Browser beschränken den Zugriff auf Low-Level-System-APIs, die erforderlich sind, um Funktionen wie Hardwarefunktionen des Systems erkennen zu können, auf dem sie verwendet werden.

Es gibt möglicherweise die Möglichkeit, ein Plugin/eine Erweiterung zu schreiben, um auf diese zuzugreifen. Über JavaScript und DOM ist diese Erkennung jedoch zu diesem Zweck eingeschränkt, und man muss ein Plugin schreiben, das für die verschiedenen Betriebssystemplattformen spezifisch ist.

Fazit: Eine solche Erkennung kann nur durch eine "gute Vermutung" geschätzt werden.

9
user1693593

Wenn Media Queries Level 4 in Browsern verfügbar ist, können wir die Abfragen "Zeiger" und "Hover" verwenden, um Geräte mit der Maus zu erkennen.

Wenn Sie diese Informationen wirklich an Javascript übertragen möchten, können Sie eine CSS-Abfrage verwenden, um bestimmte Stile gemäß dem Gerätetyp festzulegen. Anschließend können Sie getComputedStyle in Javascript verwenden, um diesen Stil zu lesen und den ursprünglichen Gerätetyp daraus abzuleiten.

Eine Maus kann jedoch jederzeit connected oder unplugged sein, und der Benutzer möchte möglicherweise zwischen Berührung und Maus wechseln. Daher müssen wir diese Änderung möglicherweise erkennen und anbieten, die Schnittstelle zu wechseln oder dies automatisch zu tun.

7
joeytwiddle

Seit 2018 gibt es eine gute und zuverlässige Möglichkeit, zu ermitteln, ob ein Browser über eine Maus (oder ein ähnliches Eingabegerät) verfügt: CSS4-Interaktionsfunktionen, die bereits von den meisten modernen Browsern unterstützt werden (und der Rest wird folgen) bald). 

W3C:

Die Zeiger-Medienfunktion wird verwendet, um die Anwesenheit und Genauigkeit abzufragen eines Zeigegeräts wie einer Maus.

Siehe die folgenden Optionen:

    /* The primary input mechanism of the device includes a 
pointing device of limited accuracy. */
    @media (pointer: coarse) { ... }

    /* The primary input mechanism of the device 
includes an accurate pointing device. */
    @media (pointer: fine) { ... }

    /* The primary input mechanism of the 
device does not include a pointing device. */
    @media (pointer: none) { ... }

    /* Primary input mechanism system can 
       hover over elements with ease */
    @media (hover: hover) { ... }

    /* Primary input mechanism cannot hover 
       at all or cannot conveniently hover 
       (e.g., many mobile devices emulate hovering
       when the user performs an inconvenient long tap), 
       or there is no primary pointing input mechanism */
    @media (hover: none) { ... }

    /* One or more available input mechanism(s) 
       can hover over elements with ease */
    @media (any-hover: hover) { ... }


    /* One or more available input mechanism(s) cannot 
       hover (or there are no pointing input mechanisms) */
    @media (any-hover: none) { ... }

Medienabfragen können auch in JS verwendet werden:

if(window.matchMedia("(any-hover: none)").matches) {
    // do sth
}

Verbunden:

https://drafts.csswg.org/mediaqueries/#mf-interaction

Erkennen, ob ein Clientgerät Folgendes unterstützt: Hover und: Fokusstatus

6
Blackbam

Könnten Sie den Benutzer dazu auffordern, auf einen Link oder eine Schaltfläche zu klicken, um die richtige Version der Anwendung "einzugeben", da Sie sowieso eine Möglichkeit zum Wechseln zwischen den Schnittstellen anbieten möchten. Dann könnten Sie sich an ihre Präferenz für zukünftige Besuche erinnern. Es ist kein High-Tech, aber zu 100% zuverlässig :-)

6
Brandan

@SamuelRossille Kein Browser, den ich kenne, macht leider das Vorhandensein (oder das Fehlen davon) einer Maus preis.

Nachdem dies gesagt wurde, müssen wir nur versuchen, mit unserer bestehenden Option das Beste zu tun, was wir können ... Events. Ich weiß, dass es nicht genau das ist, wonach du suchst ... Einig ist, dass es derzeit alles andere als ideal ist.

Wir können unser Bestes tun, um herauszufinden, ob ein Benutzer zu einem bestimmten Zeitpunkt eine Maus oder eine Berührung verwendet. Hier ist ein schnelles und schmutziges Beispiel mit jQuery & Knockout:

//namespace
window.ns = {};

// for starters, we'll briefly assume if touch exists, they are using it - default behavior
ns.usingTouch = ko.observable(Modernizr.touch); //using Modernizr here for brevity.  Substitute any touch detection method you desire

// now, let's sort out the mouse
ns.usingMouse = ko.computed(function () {
    //touch
    if (ns.usingTouch()) {
        //first, kill the base mousemove event
        //I really wish browsers would stop trying to handle this within touch events in the first place
        window.document.body.addEventListener('mousemove', function (e) {
            e.preventDefault();
            e.stopImmediatePropagation();
        }, true);

        //remove mouse class from body
        $('body').removeClass("mouse");

        //switch off touch listener
        $(document).off(".ns-touch");

        // switch on a mouse listener
        $(document).on('mousemove.ns-mouse', function (e) {
            if (Math.abs(window.lastX - e.clientX) > 0 || window.lastY !== e.clientY) {
                ns.usingTouch(false);  //this will trigger re-evaluation of ns.usingMouse() and result in ns.usingMouse() === true
            }
        });

        return false;
    }
    //mouse
    else {
        //add mouse class to body for styling
        $('body').addClass("mouse");

        //switch off mouse listener
        $(document).off(".ns-mouse");

        //switch on a touch listener
        $(document).on('touchstart.ns-touch', function () { ns.usingTouch(true) });

        return true;
    }
});

//tests:
//ns.usingMouse()
//$('body').hasClass('mouse');

Sie können jetzt usingMouse () binden/abonnieren & usingTouch () und/oder Ihre Schnittstelle mit der Klasse body.mouse formatieren. Die Benutzeroberfläche wechselt hin und her, sobald ein Mauszeiger bei Touchstart erkannt wird.

Hoffentlich haben wir bald einige bessere Optionen von den Browseranbietern.

4
daredev

Warum erkennen Sie nicht einfach, ob es die Fähigkeit hat, Berührungen wahrzunehmen und/oder auf Mausbewegungen zu reagieren?

// This will also return false on
// touch-enabled browsers like Chrome
function has_touch() {
  return !!('ontouchstart' in window);
}

function has_mouse() {
  return !!('onmousemove' in window);
}
2
iblue

Das hat in einer ähnlichen Situation für mich funktioniert. Angenommen, der Benutzer hat keine Maus, bis Sie eine kurze Reihe aufeinanderfolgender Mausbewegungen sehen, ohne dass Maus-Downs oder Mouseups dazwischenliegen. Nicht sehr elegant, aber es funktioniert.

var mousedown = false;
var mousemovecount = 0;
function onMouseDown(e){
    mousemovecount = 0;
    mousedown = true;
}
function onMouseUp(e){
    mousedown = false;
    mousemovecount = 0;
}
function onMouseMove(e) {
    if(!mousedown) {
        mousemovecount++;
        if(mousemovecount > 5){
            window.removeEventListener('mousemove', onMouseMove, false);
            console.log("mouse moved");
            $('body').addClass('has-mouse');
        }
    } else {
        mousemovecount = 0;
    }
}
window.addEventListener('mousemove', onMouseMove, false);
window.addEventListener('mousedown', onMouseDown, false);
window.addEventListener('mouseup', onMouseUp, false);
2

Tera-WURFL kann Ihnen die Fähigkeiten des Geräts anzeigen, das Ihre Site besucht , indem Sie die Browsersignatur mit ihrer Datenbank vergleichen. Schau es dir mal an, es ist kostenlos!

2
Gigi

das Hauptproblem, das ich hier sehe, ist, dass die meisten Touch-Geräte ein Mausereignis zusammen mit dem entsprechenden Touch-One auslösen (Touchstart -> Mousedown, Touchmove -> Mousemove usw.). Nur für die Tastatur, zuletzt für die modernen, verfügen sie über einen generischen Browser, sodass Sie nicht einmal das Vorhandensein der MouseEvent-Klasse erkennen können.

Die weniger schmerzhafte Lösung hier wäre meiner Meinung nach, beim Start ein Menü anzuzeigen (mit "alt" -Management nur für Benutzer der Tastatur) und möglicherweise die Auswahl mit localStorage/cookies/serverside zu speichern, oder die Auswahl der nächsten Option zu behalten Mal kommt der Besucher.

0
Ernoriel

Die beste Idee ist meiner Meinung nach der Listener mousemove (derzeit die beste Antwort). Ich glaube, dass diese Methode etwas angepasst werden muss. Es ist wahr, dass touchbasierte Browser sogar das Mausemove-Ereignis nachahmen, wie Sie in dieser iOS-Diskussion sehen können, also sollten wir etwas vorsichtig sein.

Es ist sinnvoll, dass berührungsbasierte Browser dieses Ereignis nur dann emulieren, wenn der Benutzer auf den Bildschirm tippt (der Finger des Benutzers ist deaktiviert). Das heißt, wir sollten während unseres Maushandlers einen Test hinzufügen, um zu sehen, welche Maustaste (falls vorhanden) während des Ereignisses gedrückt ist. Wenn keine Maustaste gedrückt wird, können wir davon ausgehen, dass eine echte Maus vorhanden ist. Wenn eine Maustaste gedrückt ist, bleibt der Test nicht schlüssig.

Wie würde dies umgesetzt werden? Diese Frage zeigt, dass die zuverlässigste Methode, um zu prüfen, welche Maustaste während einer Mausbewegung gedrückt wird, tatsächlich drei Ereignisse auf Dokumentebene zu überwachen: Mauszeiger, Mausedown und Mouseup. Das Auf und Ab setzt nur ein globales boolesches Flag. Der Zug führt den Test durch. Wenn Sie eine Bewegung haben und der Boolesche Wert falsch ist, können wir davon ausgehen, dass eine Maus vorhanden ist. Siehe Frage für genaue Codebeispiele.

Ein abschließender Kommentar .. Dieser Test ist nicht ideal, da er nicht in der Ladezeit ausgeführt werden kann. Daher würde ich, wie zuvor vorgeschlagen, eine progressive Verbesserungsmethode verwenden. Zeigen Sie standardmäßig eine Version an, die die für die Maus spezifische Hover-Schnittstelle nicht unterstützt. Wenn eine Maus erkannt wird, aktivieren Sie diesen Modus in Runtime mit JS. Dies sollte dem Benutzer so nahtlos wie möglich erscheinen.

Um Änderungen in der Benutzerkonfiguration zu unterstützen (dh die Maus wurde getrennt), können Sie regelmäßig einen neuen Test durchführen. Ich bin jedoch der Meinung, dass es in diesem Fall besser ist, den Benutzer einfach über die beiden Modi zu informieren und die Benutzer manuell zwischen ihnen wechseln zu lassen (ähnlich wie bei der Auswahl von Mobilgeräten/Desktops, die jederzeit rückgängig gemacht werden können).

0
talkol

Eine einfache Lösung in jQuery zum Erkennen der Mausnutzung, die das Problem löst, bei dem mobile Geräte auch ein "Mausemove-Ereignis" auslösen. Fügen Sie einfach einen Touchstart-Listener hinzu, um den Mausemove-Listener zu entfernen, damit er bei Berührung nicht ausgelöst wird.

$('body').one('touchstart.test', function(e) {
  // Remove the mousemove listener for touch devices
  $('body').off('mousemove.test');
}).one('mousemove.test', function(e) {
  // MOUSE!
});

Natürlich könnte das Gerät immer noch eine UND-Maus sein, aber die obigen Angaben garantieren, dass eine echte Maus verwendet wurde.

0
suncat100

Ich habe Stunden damit verbracht, dieses Problem für meine Phonegap-App herauszufinden, und mir kam dieser Hack auf. Es wird eine Konsolenwarnung generiert, wenn das ausgelöste Ereignis ein "passives" Ereignis ist, dh es wird keine Änderung ausgelöst, aber es funktioniert! Ich würde mich für Ideen zur Verbesserung oder für eine bessere Methode interessieren. Dies erlaubt es mir jedoch, $ .touch () universell zu verwenden.

$(document).ready(function(){
  $("#aButton").touch(function(origElement, origEvent){
    console.log('Original target ID: ' + $(origEvent.target).attr('id'));
  });
});

$.fn.touch = function (callback) {
    var touch = false;
    $(this).on("click", function(e){
        if (!touch)
        {
            console.log("I click!");
            let callbackReal = callback.bind(this);
            callbackReal(this, e);
        }else{
            touch = true;
        }
        touch = false;
    });
    $(this).on("touchstart", function(e){
        if (typeof e.touches != typeof undefined)
        {
            e.preventDefault();
            touch = true;
            console.log("I touch!");
            let callbackReal = callback.bind(this);
            callbackReal(this, e);
        }
    });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<button id="aButton">A Button</button>

0
Jay

Ich glaube nicht, dass es möglich ist, ein berührungsloses Gerät zu identifizieren (meines Wissens natürlich). Das Hauptproblem ist, dass alle Maus- und Tastaturereignisse auch von Berührungsgeräten ausgelöst werden .. __ Siehe das folgende Beispiel: Beide Alarme werden für Berührungsgeräte auf true gesetzt.

function is_touch_present() {
  return ('ontouchstart' in window) || ('onmsgesturechange' in window);
}

function is_mouse_present() {
  return (('onmousedown' in window) && ('onmouseup' in window) && ('onmousemove' in window) && ('onclick' in window) && ('ondblclick' in window) && ('onmousemove' in window) && ('onmouseover' in window) && ('onmouseout' in window) && ('oncontextmenu' in window));
}

alert("Touch Present: " + is_touch_present());
alert("Mouse Present: " + is_mouse_present());
0
Bikas

Ich bin auf die gleiche Ausgabe gestoßen, in der eine einzelne Berührung ebenfalls als Klick registriert wurde .. Nachdem ich die Kommentare der am besten bewerteten Antworten durchgelesen hatte, kam ich zu meiner eigenen Lösung:

var body = document.getElementsByTagName('body')[0];
var mouseCount = 0;

// start in an undefined state 
// (i use this to blend in elements once we decide what input is used)
var interactionMode = 'undefined';


var registerMouse = function() {
  // count up mouseCount every time, the mousemove event is triggered
  mouseCount++;

  // but dont set it instantly. 
  // instead wait 20 miliseconds (seems to be a good value for multiple move actions), 
  // if another mousemove event accoures switch to mouse as interaction 
  setTimeout(function() {
    // a touch event triggers also exactly 1 mouse move event.
    // So only if mouseCount is higher than 1 we are really moving the cursor by mouse.
    if (mouseCount > 1) {
      body.removeEventListener('mousemove', registerMouse);
      body.removeEventListener('touchend', registerTouch);

      interactionMode = 'mouse';
      console.log('now mousing');
      listenTouch();
    }

    // set the counter to zero again
    mouseCount = 0;
  }, 20);
};

var registerTouch = function() {
  body.removeEventListener('mousemove', registerMouse);
  body.removeEventListener('touchend', registerTouch);

  interactionMode = 'touch';
  console.log('now touching');
  mouseCount = 0;

  listenMouse();
};

var listenMouse = function() {
  body.addEventListener("mousemove", registerMouse);
};
var listenTouch = function() {
  body.addEventListener("touchend", registerTouch);
};

listenMouse();
listenTouch();

// after one second without input, assume, that we are touching
// could be adjusted to several seconds or deleted
// without this, the interactionMode would stay 'undefined' until first mouse or touch event
setTimeout(function() {
  if (!body.classList.contains('mousing') || body.classList.contains('touching')) {
    registerTouch();
  }
}, 1000);
/* fix, so that scrolling is possible */

html,
body {
  height: 110%;
}
Mouse or touch me

Das einzige Problem, das ich gefunden habe, ist, dass Sie scrollen müssen, um ein Berührungsereignis richtig zu erkennen. Eine einzelne Registerkarte (Berührung) kann zu Problemen führen.

Ich habe einige Tests auf verschiedenen PCs, Linuxs, iPhone, Android-Handys und Registerkarten durchgeführt. Seltsam, dass es keine einfache kugelsichere Lösung gibt. Problem tritt auf, wenn einige, die über Touch und keine Maus verfügen, noch Touch- und Mouse-Ereignisse für die Anwendung darstellen. Da Sie nur Maus- und Nur-Maus-Instanzen unterstützen möchten, möchten Sie beides verarbeiten, was jedoch zu doppeltem Auftreten von Benutzerinteraktionen führt. Wenn Sie wissen können, dass sich keine Maus auf dem Gerät befindet, können Sie wissen, dass gefälschte/eingefügte Mausereignisse ignoriert werden. Versuchte Einstellung Flag wenn MouseMove angetroffen wird, aber einige Browser werfen gefälschte MouseMove sowie MouseUp und MouseDown. Ich habe versucht, Zeitstempel zu untersuchen, stellte jedoch fest, dass dies zu riskant war. Fazit: Ich habe festgestellt, dass die Browser, die die falschen Mausereignisse erstellt haben, immer einen einzelnen MouseMove direkt vor dem eingefügten MouseDown eingefügt haben. In 99,99% meiner Fälle gibt es bei einem System mit einer echten Maus mehrere aufeinanderfolgende MouseMove-Ereignisse - mindestens zwei. Verfolgen Sie also, ob das System auf zwei aufeinanderfolgende MouseMove-Ereignisse trifft, und geben Sie an, dass keine Maus vorhanden ist, wenn diese Bedingung niemals erfüllt ist. Dies ist wahrscheinlich zu einfach, aber es funktioniert bei allen meinen Test-Setups. Ich denke, ich bleibe dabei, bis ich eine bessere Lösung finde. - Jim W

0
jwasch

Wie andere darauf hingewiesen haben, ist das endgültige Erkennen, ob eine Maus vorhanden ist oder nicht, unzuverlässig. Dies kann sich je nach Gerät leicht ändern. Dies ist definitiv etwas, das Sie mit einem booleschen Wahr oder Falsch nicht zuverlässig tun können, zumindest im Dokumentmaßstab.

Touch-Events und Maus-Events sind exklusiv. Das kann also etwas helfen, verschiedene Maßnahmen zu ergreifen. Das Problem ist, dass die Berührungsereignisse näher an den Mausbewegungen liegen und auch ein Klickereignis auslösen.

Von Ihrer Frage aus sagen Sie, Sie möchten einen Schwebeflug für die Vorschau haben. Darüber hinaus kenne ich keine weiteren Details zu Ihrer Benutzeroberfläche. Ich bin angenommen, dass mit dem Fehlen einer Maus ein Antippen der Vorschau erfolgen soll, während ein Klick aufgrund der Hover-Vorschau eine andere Aktion ausführt.

Wenn dies der Fall ist, können Sie die Erkennung lahmlegen:

Vor einem Onclick-Ereignis wird immer ein Onmouseover-Ereignis mit einer Maus angezeigt. Notieren Sie sich also, dass sich der Mauszeiger auf dem Element befindet, auf das geklickt wurde.

Sie können dies mit einem dokumentweiten Onmousemove-Ereignis tun. Mit event.target können Sie aufzeichnen, auf welchem ​​Element sich der Mauszeiger befindet. Anschließend können Sie in Ihren Onclick-Ereignissen überprüfen, ob sich der Mauszeiger tatsächlich über dem angeklickten Element (oder einem untergeordneten Element des Elements) befindet.

Von dort aus können Sie wählen, ob Sie sich für beide auf das Click-Ereignis verlassen und je nach Ergebnis eine A- oder B-Aktion durchführen möchten. Die B-Aktion könnte nichts sein, wenn einige Touch-Geräte kein Klickereignis ausgeben (stattdessen müssen Sie sich auf viele * Ereignisse verlassen).

0
Luke

Schauen Sie sich modenizr an. Eine der Funktionen ist Touch

http://modernizr.com/docs/#features-misc

Obwohl ich nicht vollständig getestet habe, scheint es sehr gut zu funktionieren 

Auch dies ist von der Modernizr-Seite verlinkt http://www.html5rocks.com/de/mobile/touchandmouse/

0
exussum

Habe gerade eine Lösung gefunden, die ich ziemlich elegant finde.

// flag as mouse interaction by default
var isMouse = true;

// detect a touch event start and flag it
$(window).on('touchstart', function () {
  // if triggers touchstart, toggle flag
  // since touch events come before mouse event / click
  // callback of mouse event will get in callback
  // `isMouse === false`
  isMouse = false;
});

// now the code that you want to write
// should also work with `mouse*` events
$('a.someClass').on('click', function () {
  if (isMouse) {
    // interaction with mouse event
    // ...
  } else {
    // reset for the next event detection
    // this is crucial for devices that have both
    // touch screen and mouse
    isMouse = true;

    // interaction with touch event
    // ...
  }
});
0
Koala Yeung