Обнаружение IF, если навести курсор на элемент с помощью jQuery
Я не ищу действия для вызова при наведении курсора, а вместо этого, чтобы узнать, находится ли элемент в данный момент. Например:
$('#elem').mouseIsOver(); // returns true or false
Есть ли метод jQuery, который выполняет это?
12 ответов
Оригинальный (и правильный) ответ:
Ты можешь использовать 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, так что.
Работало в jQuery 1.7.x.
Он перестал работать в 1.9.1, когда кто-то сообщил мне об этом, и мы все подумали, что это связано с удалением jQuery
hover
псевдоним для обработки событий в этой версии.Он снова работал в jQuery 1.10.1 и 2.0.2 (возможно, 2.0.x), что говорит о том, что сбой в 1.9.x был ошибкой или не так, как мы думали в предыдущем пункте.
Если вы хотите проверить это в конкретной версии jQuery, просто откройте пример JSFidlle в начале этого ответа, перейдите к нужной версии jQuery и нажмите "Выполнить". Если цвет меняется при наведении, это работает.
,
Редактировать 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 + Web Dev".
Использование:
var hovered = $("#parent").find("#element:hover").length;
jQuery 1.9+
Это не работает в jQuery 1.9. Сделал этот плагин на основе ответа пользователя 2444818.
jQuery.fn.mouseIsOver = function () {
return $(this).parent().find($(this).selector + ":hover").length > 0;
};
Принятый ответ не работает для меня на JQuery 2.x.is(":hover")
возвращает false при каждом вызове.
Я получил довольно простое решение, которое работает:
function isHovered(selector) {
return $(selector+":hover").length > 0
}
Установить флаг при наведении:
var over = false;
$('#elem').hover(function() {
over = true;
},
function () {
over = false;
});
Тогда просто проверьте свой флаг.
Вы можете отфильтровать свой элемент от всех наведенных элементов. Проблемный код:
element.filter(':hover')
Сохранить код:
jQuery(':hover').filter(element)
Чтобы вернуть логическое значение:
jQuery(':hover').filter(element).length===0
Пара обновлений, чтобы добавить после работы над этой темой некоторое время:
- все решения с.is(":hover") ломаются на jQuery 1.9.1
- Наиболее вероятная причина проверить, находится ли мышь над элементом, - попытаться предотвратить возникновение событий друг над другом. Например, у нас были проблемы с тем, что наш указатель мыши был запущен и завершен еще до того, как событие Mouseenter даже завершилось. Конечно, это было из-за быстрого движения мыши.
Мы использовали hoverIntent https://github.com/briancherne/jquery-hoverIntent чтобы решить эту проблему для нас. По сути это срабатывает, если движение мыши более преднамеренное. (Стоит отметить, что при нажатии и вводе мышью элемента, и выходе из него, он будет срабатывать - если вы хотите использовать один проход, то конструктор - пустая функция)
Расширяя ответ @ Мохамеда. Вы могли бы использовать небольшую инкапсуляцию
Как это:
jQuery.fn.mouseIsOver = function () {
if($(this[0]).is(":hover"))
{
return true;
}
return false;
};
Используйте это как:
$("#elem").mouseIsOver();//returns true or false
Разветвленная скрипка: http://jsfiddle.net/cgWdF/1/
Асинхронная функция в строке 38:
$( ".class#id" ).hover(function() {
Your javascript
});
Мне нравится первый ответ, но для меня это странно. При попытке проверить сразу после загрузки страницы для мыши, я должен поставить как минимум 500 миллисекунд задержки, чтобы она заработала:
$(window).on('load', function() {
setTimeout(function() {
$('img:hover').fadeOut().fadeIn();
}, 500);
});
Установка флага для ответа кинакуты кажется разумной, вы можете поместить слушателя в тело, чтобы вы могли проверить, находится ли какой-либо элемент в определенный момент.
Тем не менее, как вы хотите иметь дело с дочерними узлами? Возможно, вам следует проверить, является ли элемент предком текущего в настоящий момент элемента.
<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>
There're so many ways this can be achieved. I personally don't like styling elements directly, I'd rather add the style from css, makes things easier when trying to override or change them.
<style type="text/css">.red-bg { background: red; }</style>
$('#my_element').hover(function() {
$(this).parent().toggleClass('red-bg');
});
ИЛИ
$('#my_element').hover(function() {
$(this).parent().addClass('red-bg');
}, function() {
$(this).parent().removeClass('red-bg');
});
ИЛИ с помощью ввода и отпускания мыши
$(document).on('mouseenter', '#my_element', function() {
$(this).parent().addClass('red-bg');
});
$(document).on('mouseenter', '#my_element', function() {
$(this).parent().removeClass('red-bg');
});