Erkennen Sie IF, wenn Sie mit jQuery über einem Element schweben


149

Ich suche nicht nach einer Aktion, die beim Schweben aufgerufen werden soll , sondern nach einer Möglichkeit, festzustellen, ob ein Element gerade über dem Mauszeiger bewegt wird. Zum Beispiel:

$('#elem').mouseIsOver(); // returns true or false

Gibt es eine jQuery-Methode, die dies erreicht?


Nur für den Fall, dass jemand nach anderen Lösungen sucht stackoverflow.com/questions/1273566/…
Jo E.

1
Die Kennzeichnung als Duplikat sieht völlig falsch aus. Die Frage sagt nicht aus, was die Absicht ist, dass jemand anderes die Gedanken des OP liest und entscheidet, dass es sich um eine Kollisionserkennungsfrage handelt, und diese als doppelt markiert.
Meligy

Antworten:


305

Original (und richtig) Antwort:

Sie können is()den Selektor verwenden und überprüfen :hover.

var isHovered = $('#elem').is(":hover"); // returns true or false

Beispiel: http://jsfiddle.net/Meligy/2kyaJ/3/

(Dies funktioniert nur, wenn der Selektor mit EINEM Element übereinstimmt. Weitere Informationen finden Sie unter Bearbeiten 3)

.

Edit 1 (29. Juni 2013): (Gilt nur für jQuery 1.9.x, da es mit 1.10+ funktioniert, siehe nächste Edit 2)

Diese Antwort war zum Zeitpunkt der Beantwortung der Frage die beste Lösung. Dieser ': hover'-Selektor wurde mit der .hover()Methodenentfernung in jQuery 1.9.x entfernt.

Interessanterweise zeigt eine aktuelle Antwort von "allicarn", dass es möglich ist, :hoverals CSS-Selektor (vs. Sizzle) zu verwenden, wenn Sie ihm einen Selektor voranstellen $($(this).selector + ":hover").length > 0, und es scheint zu funktionieren!

Auch das in einer anderen Antwort erwähnte hoverIntent- Plugin sieht sehr gut aus.

Edit 2 (21. September 2013): .is(":hover") funktioniert

Aufgrund eines anderen Kommentars habe ich festgestellt, dass die ursprüngliche Art und Weise, wie ich sie gepostet habe .is(":hover"), tatsächlich immer noch in jQuery funktioniert.

  1. Es hat in jQuery 1.7.x funktioniert.

  2. In 1.9.1 funktionierte es nicht mehr, als es mir jemand meldete, und wir alle dachten, es hängt damit zusammen, dass jQuery den hoverAlias ​​für die Ereignisbehandlung in dieser Version entfernt.

  3. In jQuery 1.10.1 und 2.0.2 (möglicherweise 2.0.x) hat es wieder funktioniert, was darauf hindeutet, dass der Fehler in 1.9.x ein Fehler war oder kein absichtliches Verhalten, wie wir im vorherigen Punkt gedacht haben.

Wenn Sie dies in einer bestimmten jQuery-Version testen möchten, öffnen Sie einfach das JSFidlle-Beispiel am Anfang dieser Antwort, wechseln Sie zur gewünschten jQuery-Version und klicken Sie auf "Ausführen". Wenn sich die Farbe beim Hover ändert, funktioniert es.

.

Bearbeiten 3 (9. März 2014): Dies funktioniert nur, wenn die jQuery-Sequenz ein einzelnes Element enthält

Wie @Wilmer in den Kommentaren gezeigt hat, hat er eine Geige, die nicht einmal gegen jQuery-Versionen funktioniert, gegen die ich und andere hier getestet haben. Als ich versuchte herauszufinden, was an seinem Fall besonders ist, bemerkte ich, dass er versuchte, mehrere Elemente gleichzeitig zu überprüfen. Das warf Uncaught Error: Syntax error, unrecognized expression: unsupported pseudo: hover.

Wenn er also mit seiner Geige arbeitet, funktioniert das NICHT :

var isHovered = !!$('#up, #down').filter(":hover").length;

Während dieser DOES Arbeit:

var isHovered = !!$('#up,#down').
                    filter(function() { return $(this).is(":hover"); }).length;

Es funktioniert auch mit jQuery-Sequenzen, die ein einzelnes Element enthalten, z. B. wenn der ursprüngliche Selektor nur mit einem Element übereinstimmt oder wenn Sie .first()die Ergebnisse aufgerufen haben usw.

Dies wird auch in meinem JavaScript + Web Dev Tips & Resources Newsletter erwähnt .


1
Funktioniert super einfach. Danke Mohamed!
James Skidmore

18
Wirft einen Fehler in IE 8 : Syntax Error, unrecognized expression: hover. jquery-1.7.js line 4179.
RobG

Das ist richtig. Habe es gerade getestet. Versuchen Sie für IE6 diesen hier beschriebenen Hack peterned.home.xs4all.nl/csshover.html oder greifen Sie auf den normalen Hover zurück, fügen Sie einen Status hinzu und löschen Sie ihn später.
Meligy

1
@Meligy: Ich habe Ihre Geige gegabelt, um zu veranschaulichen, dass es nicht mit mehreren Elementen in der Auswahl funktioniert
SuperNova

1
Auch wenn Sie jQuery Mobile verwenden, ist dies ebenfalls ein Problem. Überprüfen Sie die Antwort der Geige in den Gideons und schalten Sie das Feld jQuery Mobile 1.4.4 ein. Sie können sehen, dass es dann nicht funktioniert. Ich kann das auch mit bestätigen 1.4.2 auch :(
David O'Sullivan

32

Verwenden:

var hovered = $("#parent").find("#element:hover").length;

jQuery 1.9+


1
Das funktioniert hervorragend. Beste Lösung beim Suchen nach einem Ersatz für die .hover-Funktion und: hover selector. Danke dir!
Tyler

1
Klappt wunderbar! :)
jroi_web

9

In jQuery 1.9 funktioniert es nicht. Dieses Plugin wurde basierend auf der Antwort von user2444818 erstellt.

jQuery.fn.mouseIsOver = function () {
    return $(this).parent().find($(this).selector + ":hover").length > 0;
}; 

http://jsfiddle.net/Wp2v4/1/


5

Setzen Sie eine Flagge auf Hover:

var over = false;
$('#elem').hover(function() {
  over = true;
},
function () {
  over = false;
});

Dann überprüfen Sie einfach Ihre Flagge.


Einfach, aber nicht leicht wiederzuverwenden. : /
Trevor

Schien in meiner speziellen Situation nicht zu funktionieren, aber ich stimme zu, dass dies ein guter Weg ist, um anders vorzugehen. In meinem Fall mouseleavemöchte ich bei einem Element überprüfen, ob die Maus ein anderes bestimmtes Element eingegeben hat.
James Skidmore

@JamesSkidmore - im Mouseleave-Event können Sie e.fromElementund verwenden e.toElement. Geht das so für dich?
Mrtsherman

Sie können dies aktualisieren, um einen Selektor zu verwenden, der alle zutreffenden Elemente abdeckt, und das Flag für die einzelnen Elemente mit speichern .data().
nnnnnn

@Trevor - true - Sie müssen den Status auf dem Element speichern und dann eine Funktion erstellen, die den Status des Elements (vermutlich Daten-Tag) überprüft.
Kinakuta

4

Einige Updates, die hinzugefügt werden müssen, nachdem Sie eine Weile an diesem Thema gearbeitet haben:

  1. Alle Lösungen mit .is (": hover") brechen in jQuery 1.9.1 ab
  2. Der wahrscheinlichste Grund, um zu überprüfen, ob sich die Maus noch über einem Element befindet, besteht darin, zu verhindern, dass Ereignisse übereinander ausgelöst werden. Zum Beispiel hatten wir Probleme damit, dass unser Mausblatt ausgelöst und abgeschlossen wurde, bevor unser Mouseenter-Ereignis überhaupt abgeschlossen war. Dies lag natürlich an einer schnellen Mausbewegung.

Wir haben hoverIntent https://github.com/briancherne/jquery-hoverIntent verwendet , um das Problem für uns zu lösen. Im Wesentlichen wird es ausgelöst, wenn die Mausbewegung bewusster ist. (Eine Sache zu beachten ist, dass es ausgelöst wird, wenn beide Maus ein Element betritt und verlässt - wenn Sie nur einen Durchgang verwenden möchten, übergibt der Konstruktor eine leere Funktion)


4

Sie können Ihr Element aus allen schwebenden Elementen filtern. Problematischer Code:

element.filter(':hover')

Code speichern:

jQuery(':hover').filter(element)

So geben Sie einen Booleschen Wert zurück:

jQuery(':hover').filter(element).length===0

4

Die akzeptierte Antwort hat bei JQuery 2.x bei mir nicht funktioniert. Bei .is(":hover")jedem Anruf wird false zurückgegeben.

Am Ende hatte ich eine ziemlich einfache Lösung, die funktioniert:

function isHovered(selector) {

    return $(selector+":hover").length > 0

}

3

Erweiterung auf @ Mohammeds Antwort. Sie könnten eine kleine Kapselung verwenden

So was:

jQuery.fn.mouseIsOver = function () {
    if($(this[0]).is(":hover"))
    {
        return true;
    }
    return false;
}; 

Verwenden Sie es wie:

$("#elem").mouseIsOver();//returns true or false

Geige gegabelt: http://jsfiddle.net/cgWdF/1/


6
Dazu können Sie auch Folgendes tun: jQuery.fn.mouseIsOver = function () {return $ (this [0]). is (': hover')}; weniger Code
Lathan

32
wie schwer es ist, einfach $ ('# elem') zu machen. ist (':
hover

keine schwierige Frage, sondern die Absicht wird klar zum Ausdruck gebracht. Aber für jeden ist es sein eigenes.
Gideon

1

Ich mag die erste Antwort, aber für mich ist es komisch. Wenn ich versuche, direkt nach dem Laden der Seite nach der Maus zu suchen, muss ich mindestens 500 Millisekunden Verzögerung eingeben, damit sie funktioniert:

$(window).on('load', function() {
    setTimeout(function() {
        $('img:hover').fadeOut().fadeIn();
    }, 500);
});

http://codepen.io/molokoloco/pen/Grvkx/


0

Das Setzen eines Flags pro Kinakutas Antwort erscheint vernünftig. Sie können einen Listener auf den Körper setzen, um zu überprüfen, ob zu einem bestimmten Zeitpunkt ein Element über den Mauszeiger bewegt wird.

Wie möchten Sie jedoch mit untergeordneten Knoten umgehen? Sie sollten möglicherweise überprüfen, ob das Element ein Vorfahr des aktuell schwebenden Elements ist.

<script>

var isOver = (function() {
  var overElement;
  return {

    // Set the "over" element
    set: function(e) {
      overElement = e.target || e.srcElement;
    },

    // Return the current "over" element
    get: function() {
      return overElement;    
    },

    // Check if element is the current "over" element
    check: function(element) {
      return element == overElement;
    },

    // Check if element is, or an ancestor of, the 
    // current "over" element
    checkAll: function(element) {
      while (overElement.parentNode) {
         if (element == overElement) return true;
         overElement = overElement.parentNode;
      }
      return false;
    }
  };
}());


// Check every second if p0 is being hovered over
window.setInterval( function() {
  var el = document.getElementById('p0');
  document.getElementById('msg').innerHTML = isOver.checkAll(el);
}, 1000);


</script>

<body onmouseover="isOver.set(event);">
  <div>Here is a div
    <p id="p0">Here is a p in the div<span> here is a span in the p</span> foo bar </p>
  </div>
  <div id="msg"></div>
</body>
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.