it-swarm.com.de

Wie simuliere ich einen Hover mit einem Touch-In-Touch-fähigen Browser?

Mit etwas HTML wie diesem:

<p>Some Text</p>

Dann einige CSS wie folgt:

p {
  color:black;
}

p:hover {
  color:red;
}

Wie kann ich eine lange Berührung eines berührungsfähigen Geräts zulassen, um den Hover zu replizieren? Ich kann Markup ändern/JS usw. verwenden, kann mir aber keine einfache Möglichkeit vorstellen.

112
Rich Bradshaw

OK, ich habe es geklärt! Es beinhaltet ein leichtes Ändern des CSS und das Hinzufügen einiger JS.

JQuery verwenden, um es einfach zu machen:

$(document).ready(function() {
    $('.hover').on('touchstart touchend', function(e) {
        e.preventDefault();
        $(this).toggleClass('hover_effect');
    });
});

In englischer Sprache: Wenn Sie eine Berührung starten oder beenden, schalten Sie die Klasse hover_effect ein oder aus.

Fügen Sie dann in Ihrem HTML-Code einen Klassen-Hover zu allen Objekten hinzu, mit denen dies funktionieren soll. Ersetzen Sie in Ihrem CSS jede Instanz von:

element:hover {
    rule:properties;
}

mit

element:hover, element.hover_effect {
    rule:properties;
}

Und für zusätzlichen Nutzen, fügen Sie dies auch zu Ihrem CSS hinzu:

.hover {
-webkit-user-select: none;
-webkit-touch-callout: none;        
}

Um zu stoppen, dass der Browser Sie auffordert, das Bild oder was auch immer zu kopieren/speichern/auszuwählen.

Einfach!

164
Rich Bradshaw

Alles was Sie tun müssen, ist Touchstart an ein Elternteil zu binden. So etwas wird funktionieren:

$('body').on('touchstart', function() {});

Sie müssen nichts in der Funktion tun, lassen Sie sie leer. Dies reicht aus, um Schwebeflüge bei Berührung zu erhalten, so dass sich eine Berührung eher wie: Schwebeflug und weniger wie: Aktiv verhält. iOS-Magie.

50

Versuche dies:

<script>
document.addEventListener("touchstart", function(){}, true);
</script>

Und in deinem CSS:

element:hover, element:active {
-webkit-tap-highlight-color: rgba(0,0,0,0);
-webkit-user-select: none;
-webkit-touch-callout: none /*only to disable context menu on long press*/
}

Mit diesem Code benötigen Sie keine zusätzliche .hover-Klasse!

39
Anselm

Um Ihre Hauptfrage zu beantworten: “Wie simulieren Sie einen Hover mit einem Touch-In-Touch-fähigen Browser?”

Lassen Sie einfach auf das Element "klicken" (durch Antippen des Bildschirms) und lösen Sie dann das Ereignis hover mit JavaScript aus.

var p = document.getElementsByTagName('p')[0];
p.onclick = function() {
 // Trigger the `hover` event on the paragraph
 p.onhover.call(p);
};

Dies sollte funktionieren, solange es auf Ihrem Gerät ein hover-Ereignis gibt (auch wenn es normalerweise nicht verwendet wird).

Update: Ich habe diese Technik gerade auf meinem iPhone getestet und scheint gut zu funktionieren. Probieren Sie es hier aus: http://jsfiddle.net/mathias/YS7ft/show/light/

Wenn Sie stattdessen eine "lange Berührung" zum Auslösen des Hover verwenden möchten, können Sie den obigen Code-Snippet als Ausgangspunkt verwenden und Spaß mit Timern und so haben;)

23
Mathias Bynens

Weitere verbesserte Lösung

Zuerst ging ich mit dem Ansatz von Rich Bradshaw, aber dann tauchten Probleme auf. Durch Ausführen des Ereignisses e.preventDefault () on 'touchstart' scrollt die Seite nicht mehr, und weder durch langes Drücken des Optionsmenüs noch durch Doppelklick kann die Ausführung beendet werden. 

Eine Lösung könnte sein, herauszufinden, welches Ereignis aufgerufen wird, und nur e.preventDefault () im späteren, 'touchend'. Da das 'touchmove' von scroll vor 'touchend' steht, bleibt es standardmäßig und 'click' wird ebenfalls verhindert, da es Nachworte in der Ereigniskette gibt, die auf das mobile Gerät angewendet werden.

// Binding to the '.static_parent' ensuring dynamic ajaxified content
$('.static_parent').on('touchstart touchend', '.link', function (e) {

    // If event is 'touchend' then...
    if (e.type == 'touchend') {
        // Ensuring we event prevent default in all major browsers
        e.preventDefault ? e.preventDefault() : e.returnValue = false;
    }

    // Add class responsible for :hover effect
    $(this).toggleClass('hover_effect');
});

Wenn jedoch das Optionsmenü angezeigt wird, löst es nicht mehr 'touchend' aus, das für das Umschalten der Klasse verantwortlich ist, und beim nächsten Mal wird das Schwebeflugverhalten umgekehrt und völlig durcheinander sein. 

Eine Lösung wäre dann wiederum bedingt, herauszufinden, in welchem ​​Ereignis wir gerade sind, oder einfach nur einzelne, und dann addClass () und removeClass () jeweils auf 'touchstart' verwenden. und 'touchend', um sicherzustellen, dass es immer beginnt und endet, indem es hinzugefügt bzw. entfernt wird, anstatt sich bedingt zu entscheiden. Zum Abschluss binden wir den entfernenden Callback auch an den Ereignistyp 'focusout'. Dabei bleiben Sie dafür verantwortlich, dass die Hover-Klasse eines Links gelöscht wird und möglicherweise nie wieder aufgerufen wird.

$('.static_parent').on('touchstart', '.link', function (e) {
    $(this).addClass('hover_effect');
});

$('.static_parent').on('touchend focusout', '.link', function (e) {
    // Think double click zoom still fails here
    e.preventDefault ? e.preventDefault() : e.returnValue = false;
    $(this).removeClass('hover_effect');
});

Attention: In den beiden vorherigen Lösungen treten immer noch einige Fehler auf. Auch der Doppelklick-Zoom schlägt fehl (nicht getestet).

Aufgeräumt und hoffentlich fehlerfrei (nicht :)) Javascript Solution

Now, für eine Sekunde, sauberer, aufgeräumter und reaktionsschneller, Ansatz nur mit Javascript (keine Mischung zwischen .hover-Klasse und Pseudo: hover) und von wo aus Sie Ihr Ajax-Verhalten direkt auf dem Universal (mobil und Desktop) aufrufen können. 'click' event, ich habe eine ziemlich gut beantwortete Frage gefunden, von der ich schließlich verstanden habe, wie ich Touch- und Mausereignisse zusammen mischen könnte, ohne dass mehrere Event-Rückrufe zwangsläufig die jeweils anderen Ereignisse des Events ändern Kette. Hier ist wie:

$('.static_parent').on('touchstart mouseenter', '.link', function (e) {
    $(this).addClass('hover_effect');
});

$('.static_parent').on('mouseleave touchmove click', '.link', function (e) {
    $(this).removeClass('hover_effect');

    // As it's the chain's last event we only prevent it from making HTTP request
    if (e.type == 'click') {
        e.preventDefault ? e.preventDefault() : e.returnValue = false;

        // Ajax behavior here!
    }
});
13

Der hover-Effekt der Maus kann nicht in einem Touch-Gerät implementiert werden. Wenn ich in safariios mit der gleichen Situation auftritt, habe ich :active in css verwendet, um einen Effekt zu erzielen.

dh.

p:active {
  color:red;
}

In meinem Fall kann es sein, dass dies auch der Fall ist, das ohne Javascript verwendet werden kann. Einfach mal probieren.

3
sijo vijayan

Fügen Sie diesen Code hinzu und setzen Sie dann die Klasse "tapHover" für Elemente, die Sie auf diese Weise bearbeiten möchten. Wenn Sie ein Element antippen, erhält es die Pseudoklasse ": hover" und die Klasse "tapped". Klickereignis wird verhindert ..__ Beim zweiten Tippen auf dasselbe Element wird das Klickereignis ausgelöst.

// Activate only in devices with touch screen
if('ontouchstart' in window)
{
    // this will make touch event add hover pseudoclass
    document.addEventListener('touchstart', function(e) {}, true);

    // modify click event
    document.addEventListener('click', function(e) {
        // get .tapHover element under cursor
        var el = jQuery(e.target).hasClass('tapHover')
            ? jQuery(e.target)
            : jQuery(e.target).closest('.tapHover');

        if(!el.length)
            return;

        // remove tapped class from old ones
        jQuery('.tapHover.tapped').each(function() {
            if(this != el.get(0))
                jQuery(this).removeClass('tapped');
        });

        if(!el.hasClass('tapped'))
        {
            // this is the first tap
            el.addClass('tapped');
            e.preventDefault();
            return false;
        }
        else
        {
            // second tap
            return true;
        }
    }, true);
}
.box {
	float:		left;
	
	display:	inline-block;
	margin:		50px 0 0 50px;
	width:		100px;
	height:		100px;
	overflow:	hidden;
	
	font-size:	20px;
	
	border:		solid 1px black;
}
.box.tapHover {
	background:	yellow;
}
.box.tapped {
	border:		solid 3px red;
}
.box:hover {
	background:	red;
}
<div class="box" onclick="this.innerHTML = Math.random().toFixed(5)"></div>
<div class="box tapHover" onclick="this.innerHTML = Math.random().toFixed(5)"></div>
<div class="box tapHover" onclick="this.innerHTML = Math.random().toFixed(5)"></div>

2
l00k

Eine Möglichkeit wäre es, den Hover-Effekt auszuführen, wenn die Berührung beginnt, und dann den Hover-Effekt zu entfernen, wenn sich die Berührung bewegt oder endet.

Dies ist, was Apple über touch handling im Allgemeinen zu sagen hat, da Sie das iPhone erwähnen.

1
drawnonward

Ohne geräte- oder Browser-spezifische JS bin ich ziemlich sicher, dass Sie kein Glück haben.

Edit: Ich dachte, Sie wollten das vermeiden, bis ich Ihre Frage noch einmal gelesen habe. Bei Mobile Safari können Sie sich registrieren, um alle Berührungsereignisse zu erhalten, die denen von nativen UIView-Geräten ähneln. Kann die Dokumentation jetzt nicht finden, wird es jedoch versuchen.

1

Mein persönlicher Geschmack ist es, die :hover-Stile ebenfalls dem :focus-Status zuzuordnen, wie:

p {
    color: red;
}

p:hover, p:focus {
    color: blue;
}

Dann mit folgendem HTML:

<p id="some-p-tag" tabindex="-1">WOOOO</p>

Und das folgende JavaScript:

$("#some-p-tag").on("touchstart", function(e){
    e.preventDefault();
    var $elem = $(this);

    if($elem.is(":focus")) {
        //this can be registered as a "click" on a mobile device, as it's a double tap
        $elem.blur()
    }
    else {
        $elem.focus();
    }
});
1
pimbrouwers

Eine Mischung aus nativem Javascript und jQuery:

var gFireEvent = function (oElem,sEvent) 
{
 try {
 if( typeof sEvent == 'string' && o.isDOM( oElem ))
 {
  var b = !!(document.createEvent),
     evt = b?document.createEvent("HTMLEvents"):document.createEventObject();
  if( b )    
  {  evt.initEvent(sEvent, true, true ); 
    return !oElem.dispatchEvent(evt);
  }
  return oElem.fireEvent('on'+sEvent,evt);
 }
 } catch(e) {}
 return false;
};


// Next you can do is (bIsMob etc you have to determine yourself):

   if( <<< bIsMob || bIsTab || bisTouch >>> )
   {
     $(document).on('mousedown', function(e)
     {
       gFireEvent(e.target,'mouseover' );
     }).on('mouseup', function(e)
     {
       gFireEvent(e.target,'mouseout' );
     });
   }
0
Codebeat

Die einfachste Lösung, die ich gefunden habe: Ich hatte einige <span> -Tags mit: hover-CSS-Regeln in ihnen. Ich habe für <a href = "javascript: void (0)"> und voilà gewechselt. Die Hover-Stile in iOS begannen zu funktionieren.

0
Becario Senior

Gelöst 2019 - Schweben Sie bei Berührung

Es scheint jetzt am besten, zu vermeiden, Schwebeflug mit ios oder Berührung generell zu verwenden. Der folgende Code gilt für Ihre CSS, solange die Berührung beibehalten wird und keine anderen iOS-Flyouts. Mach das;

  1. Jquery add: $ ("p"). On ("touchstart", function (e) {$ (this) .focus (); e.preventDefault ();});

  2. CSS: Ersetzen Sie p: hover durch p: focus und fügen Sie p: active hinzu 

Optionen;

  • jquery p Selector durch eine beliebige Klasse ersetzen etc

  • damit der Effekt erhalten bleibt, halten Sie auch p: hover gedrückt und fügen Sie body {Cursor: Ponter;} hinzu, so dass ein Tippen an einer beliebigen Stelle ihn beendet

  • versuche Click & Mouseover-Events sowie Touchstart im gleichen Code (aber nicht getestet).

  • e.preventDefault () entfernen; um benutzern zu ermöglichen, ios flyouts zu verwenden, zb kopieren

Anmerkungen 

  • nur für Textelemente getestet, kann ios Eingaben usw. unterschiedlich behandeln

  • nur auf iPhone XR iOS 12.1.12 und iPad 3 iOS 9.3.5 mit Safari oder Chrome getestet.

0
darren

Verwendung kann auch CSS verwenden, den verborgenen Link mit Fokus und aktiv (für IE7 und darunter) versehen. Beispiel für ein ul-Menü in einem div mit Klassenmenü:

.menu ul ul {display:none; position:absolute; left:100%; top:0; padding:0;}
.menu ul ul ul {display:none; position:absolute; top:0; left:100%;}
.menu ul ul a, .menu ul ul a:focus, .menu ul ul a:active { width:170px; padding:4px 4%; background:#e77776; color:#fff; margin-left:-15px; }
.menu ul li:hover > ul { display:block; }
.menu ul li ul li {margin:0;}

Es ist spät und ungeprüft, sollte funktionieren ;-)

0
Mark Groen