Визначте IF, якщо навести курсор на елемент за допомогою jQuery


150

Я не шукаю дії для виклику під час наведення курсору, а замість цього способу визначити, чи елемент накладений на даний момент. Наприклад:

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

Чи існує метод jQuery, який виконує це?


На всякий випадок, якщо хтось шукає інші рішення stackoverflow.com/questions/1273566/…
Джо Е.

1
Позначення як дубліката виглядає зовсім неправильно. Питання не говорить про те, що має намір, щоб хтось інший прочитав розум ОП та вирішив, що це питання виявлення зіткнення та позначити як дублікат.
Мелігія

Відповіді:


306

Оригінальний (і правильний) відповідь:

Ви можете використовувати is()та перевірити вибір :hover.

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

Приклад: http://jsfiddle.net/Meligy/2kyaJ/3/

(Це працює лише тоді, коли селектор відповідає максимуму ОДИН елемент. Докладніше див. Редагувати 3)

.

Редагувати 1 (29 червня 2013 р.): (Застосовується лише для jQuery 1.9.x, оскільки це працює з 1.10+, див. Наступне редагування 2)

Ця відповідь була найкращим рішенням на той момент, коли відповіли на запитання. Цей селектор ': hover' було видалено .hover()методом видалення у jQuery 1.9.x.

Цікаво, що нещодавня відповідь "allicarn" показує, що можна використовувати :hoverяк селектор CSS (проти Sizzle), коли ви додаєте його до селектора $($(this).selector + ":hover").length > 0, і він, здається, працює!

Також дуже добре виглядає плагін hoverIntent, згаданий в іншій відповіді.

Редагування 2 (21 вересня 2013 р.): .is(":hover") Працює

На підставі іншого коментаря я помітив, що оригінальний спосіб, який я опублікував .is(":hover"), насправді все ще працює в jQuery, так.

  1. Він працював у jQuery 1.7.x.

  2. Він припинив роботу в 1.9.1, коли хтось повідомив про це мені, і всі ми думали, що це пов'язано з тим, що jQuery видалив hoverпсевдонім для обробки подій у цій версії.

  3. Він знову працював у jQuery 1.10.1 та 2.0.2 (можливо 2.0.x), що говорить про те, що помилка в 1.9.x була помилкою чи не навмисною поведінкою, як ми думали в попередньому пункті.

Якщо ви хочете перевірити це у певній версії jQuery, просто відкрийте приклад JSFidlle на початку цієї відповіді, перейдіть на потрібну версію jQuery і натисніть "Виконати". Якщо колір змінюється на наведення курсора, він працює.

.

Edit 3 (9 березня 2014 р.): Він працює лише тоді, коли послідовність jQuery містить один елемент

Як показав @Wilmer у коментарях, у нього є загадка, яка навіть не працює проти версій jQuery, на які я протестували та інші. Коли я намагався знайти щось особливе у його справі, я помітив, що він намагався перевірити декілька елементів одночасно. Це кидали Uncaught Error: Syntax error, unrecognized expression: unsupported pseudo: hover.

Отже, працюючи зі своєю загадкою, це НЕ працює:

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

У той час як цього робить роботу:

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

Він також працює з послідовностями jQuery, які містять один елемент, наприклад, якщо оригінальний селектор відповідав лише одному елементу, або якщо ви викликали .first()результати тощо.

Про це також посилається в моєму бюлетені Поради щодо ресурсів і веб-розробників JavaScript + .


1
Працює чудово, просто. Дякую Мохамед!
Джеймс Скідмор

18
Видає помилку в IE 8: Syntax Error, unrecognized expression: hover. jquery-1.7.js line 4179.
RobG

Це правда. Просто перевірив це. Для IE6 спробуйте цей хак, описаний тут peterned.home.xs4all.nl/csshover.html, або поверніться до звичайного наведення курсору, додайте стан і очистіть його згодом вид рішення.
Мелігія

1
@Meligy: Я запропонував вашій загадці проілюструвати, що вона не працює з декількома пунктами у виборі: jsfiddle.net/p34n8
SuperNova

1
Крім того, якщо ви використовуєте мобільний jQuery, він відкручує його - перевірте скрипку у відповіді на відеозаписи та увімкніть поле jQuery Mobile 1.4.4, і ви побачите, що воно не працює ... Я можу підтвердити те саме 1.4.2 також :(
Девід О'Салліван

32

Використання:

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

jQuery 1.9+


1
Це працює чудово добре. Найкраще рішення знайдено під час перегляду заміни функції .hover та: вибору курсора. Дякую!
Тайлер

1
Працює як шарм! :)
jroi_web

9

У jQuery 1.9 він не працює. Цей плагін зроблений на основі відповіді користувача2444818.

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

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


5

Встановіть прапор на наведення курсора:

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

Тоді просто перевірте свій прапор.


Простий, але не легко використаний. : /
Тревор

Здається, це не працювало в моїй конкретній ситуації, але я погоджуюся, що це хороший спосіб піти інакше. У моєму випадку, коли я mouseleaveодин елемент, я хочу перевірити, чи введена миша іншим конкретним елементом.
Джеймс Скідмор

@JamesSkidmore - у події mouseleave ви можете використовувати e.fromElementі e.toElement. Це вам допоможе?
mrtsherman

Ви можете оновити це, використовуючи селектор, який охоплює всі застосовні елементи, і зберігати прапор на окремих елементах за допомогою .data().
nnnnnn

@Trevor - true - вам потрібно буде зберегти стан на елементі, а потім створити функцію, яка перевіряє (імовірно тег даних) стан елемента.
кінакута

4

Пара оновлень, які потрібно додати, попрацювавши над цією темою:

  1. усі рішення з .is (": hover") розбиваються на jQuery 1.9.1
  2. Найбільш вірогідною причиною перевірити, чи миша все ще перебуває над елементом, є спроба запобігти появі подій один на одного. Наприклад, у нас виникли проблеми із запуском і завершенням нашої миші, ще до того, як подія мишоцентру навіть завершиться. Звичайно, це було через швидкий рух миші.

Ми вирішили проблему для нас hoverIntent https://github.com/briancherne/jquery-hoverIntent . По суті, він спрацьовує, якщо рух миші є більш навмисним. (одне, що слід зазначити, це те, що він запустить як мишу, що вводить елемент, так і залишає - якщо ви хочете лише використовувати один пропуск конструктор порожню функцію)


4

Ви можете відфільтрувати свій елемент з усіх завислих елементів. Проблемний код:

element.filter(':hover')

Зберегти код:

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

Щоб повернути булеве:

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

4

Прийнята відповідь не працювала для мене на JQuery 2.x .is(":hover")повертає помилку при кожному дзвінку.

Я закінчив досить просте рішення, яке працює:

function isHovered(selector) {

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

}

3

Розгортається на відповідь @ Мохамеда. Ви можете використати трохи капсулювання

Подобається це:

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

Використовуйте його так:

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

Розділена скрипка: http://jsfiddle.net/cgWdF/1/


6
для цього ви можете також зробити: jQuery.fn.mouseIsOver = function () {return $ (this [0]). is (': hover')}; менший код
Латан

32
як важко просто зробити $ ('# elem'). is (': hover')
luckykrrish

не питання важко, але більше наміри чітко виражені. Але у кожного своє.
Гедеон

1

Мені подобається перша відповідь, але для мене це дивно. При спробі перевірити мишкою відразу після завантаження сторінки, я повинен ввести принаймні 500 мілісекундну затримку, щоб вона працювала:

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

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


0

Якщо встановити прапор на відповідь кінакути, здається розумним, ви можете поставити слухача на тіло, щоб ви могли перевірити, чи якийсь елемент навішується в певний момент.

Однак як ви хочете мати справу з дитячими вузлами? Вам, можливо, слід перевірити, чи елемент є родоначальником елемента, що перебуває в даний момент.

<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>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.