Вы используете объект, содержащий ссылку нулевого значения. Таким образом, он дает пустое исключение. В примере строковое значение равно null, и при проверке его длины произошло исключение.
Пример:
string value = null;
if (value.Length == 0) // <-- Causes exception
{
Console.WriteLine(value); // <-- Never reached
}
Ошибка исключения:
Необработанное исключение:
System.NullReferenceException: ссылка на объект не установлена в экземпляр объекта. в Program.Main ()
blockquote>
Установите тайм-аут в мыши, чтобы затухать и сохранить возвращаемое значение для данных в объекте. Затем, onmouseover, отмените таймаут, если в данных есть значение.
Удалите данные при обратном вызове fadeout.
На самом деле дешевле использовать mouseenter / mouseleave, потому что они не стреляйте в меню при стрельбе по мыши / мыши.
Вот техника, которая не полагается на jquery и использует собственный DOM matches
API . Он использует префиксы поставщиков для поддержки браузеров, возвращающихся в IE9. См. matchselector на caniuse.com для получения полной информации.
Сначала создайте функцию matchSelector, например:
var matchesSelector = (function(ElementPrototype) {
var fn = ElementPrototype.matches ||
ElementPrototype.webkitMatchesSelector ||
ElementPrototype.mozMatchesSelector ||
ElementPrototype.msMatchesSelector;
return function(element, selector) {
return fn.call(element, selector);
};
})(Element.prototype);
Затем, чтобы обнаружить зависание:
var mouseIsOver = matchesSelector(element, ':hover');
Расширяясь от того, что сказал Happytime harry, обязательно используйте функцию .data () jquery для хранения идентификатора таймаута. Это так, что вы можете легко получить идентификатор таймаута, когда «mouseenter» запускается на этом же элементе позже, что позволяет вам исключить запуск триггера для вашей всплывающей подсказки.
Я ответил на это в другом вопросе со всеми подробностями, которые могут вам понадобиться:
Обнаруживать IF, зависающий над элементом с помощью jQuery (на момент написания имеется 99 секунд)
В принципе, вы можете сделать что-то вроде:
var ishovered = oi.is(":hover");
Это работает, только если oi
- объект jQuery, содержащий один элемент. Если имеется несколько элементов, то вам необходимо применить к каждому элементу, например:
var hoveredItem = !!$('ol>li').filter(function() { return $(this).is(":hover"); });
// not .filter(':hover'), as we can't apply :hover on multiple elements
Это было протестировано, начиная с jQuery 1.7.
Я вижу, что таймауты используются для этого много, но в контексте события вы не можете посмотреть на координаты, например:
function areXYInside(e){
var w=e.target.offsetWidth;
var h=e.target.offsetHeight;
var x=e.offsetX;
var y=e.offsetY;
return !(x<0 || x>=w || y<0 || y>=h);
}
В зависимости от контекста вам может потребоваться (this == e.target) перед вызовом areXYInside (e).
fyi- Я рассматриваю этот подход внутри обработчика dragLeave, чтобы подтвердить, что событие dragLeave не было вызванный входом в дочерний элемент. Если вы каким-то образом не проверяете, что вы все еще находитесь внутри родительского элемента, вы можете ошибочно принять меры, которые предназначены только для тех случаев, когда вы действительно оставляете родителя.
EDIT: это хорошая идея, но не работают достаточно последовательно. Возможно, с небольшими ухищрениями.
Я не мог использовать ни одно из приведенных выше предложений. Почему я предпочитаю свое решение? Этот метод проверяет, находится ли мышь над элементом в любое время, выбранным вами. Mouseenter и: зависание - это круто, но mouseenter запускается только при перемещении мыши, а не при перемещении элемента под мышью. : hover довольно милый, но ... IE
Итак, я делаю это:
Нет 1. храните мышь x, y позицию каждый раз, когда вам нужно, No 2. проверьте, находится ли мышь над любым из элементов, которые соответствуют запросу, делают вещи ... например, запускают событие mouseenter
// define mouse x, y variables so they are traced all the time
var mx = 0; // mouse X position
var my = 0; // mouse Y position
// update mouse x, y coordinates every time user moves the mouse
$(document).mousemove(function(e){
mx = e.pageX;
my = e.pageY;
});
// check is mouse is over an element at any time You need (wrap it in function if You need to)
$("#my_element").each(function(){
boxX = $(this).offset().left;
boxY = $(this).offset().top;
boxW = $(this).innerWidth();
boxH = $(this).innerHeight();
if ((boxX <= mx) &&
(boxX + 1000 >= mx) &&
(boxY <= my) &&
(boxY + boxH >= my))
{
// mouse is over it so you can for example trigger a mouseenter event
$(this).trigger("mouseenter");
}
});
Мне было нужно что-то точно, как это (в немного более сложной среде, и решение с большим количеством «мышь» и «мышь» не работало должным образом), поэтому я создал небольшой плагин jquery, который добавляет метод ismouseover.
//jQuery ismouseover method
(function($){
$.mlp = {x:0,y:0}; // Mouse Last Position
function documentHandler(){
var $current = this === document ? $(this) : $(this).contents();
$current.mousemove(function(e){jQuery.mlp = {x:e.pageX,y:e.pageY}});
$current.find("iframe").load(documentHandler);
}
$(documentHandler);
$.fn.ismouseover = function(overThis) {
var result = false;
this.eq(0).each(function() {
var $current = $(this).is("iframe") ? $(this).contents().find("body") : $(this);
var offset = $current.offset();
result = offset.left<=$.mlp.x && offset.left + $current.outerWidth() > $.mlp.x &&
offset.top<=$.mlp.y && offset.top + $current.outerHeight() > $.mlp.y;
});
return result;
};
})(jQuery);
Тогда в любом месте документа вы вызываете его так, и он возвращает true или false:
$("#player").ismouseover()
Я тестировал его на IE7 +, Chrome 1+ и Firefox 4 и работает нормально.
iframe
. Поскольку событие mousemove
не срабатывает над iframe
, а Mouse i> Последняя i> Позиция i> не обновляется.
– Gabriel Diaconescu
2 April 2012 в 13:39
Чистая и элегантная проверка наведения:
if ($('#element:hover').length != 0) {
// do something ;)
}
Просто примечание об популярном и полезном ответе Артура Голдсмита выше: если вы перемещаете мышь из одного элемента в другой в IE (по крайней мере до IE 9), у вас могут возникнуть проблемы с тем, чтобы это правильно работало, если новый элемент имеет прозрачный фон (который он по умолчанию). Моим обходным путем явился новый элемент прозрачного фонового изображения.
Это был бы самый простой способ сделать это!
function(oi)
{
if(!$(oi).is(':hover')){$(oi).fadeOut(100);}
}
Вы можете использовать события mousePoint и mouseleave jQuery. Вы можете установить флаг, когда мышь входит в нужную область, и удалите флаг, когда он покинет область.
Вот функция, которая помогает вам проверить, находится ли мышь внутри элемента или нет. Единственное, что вам нужно сделать, - это вызвать функцию, в которой вы можете связать объект EventObject, связанный с ядром. что-то вроде этого:
$("body").mousemove(function(event){
element_mouse_is_inside($("#mycontainer", event, true, {});
});
Вы можете увидеть исходный код здесь в github или в нижней части сообщения:
https://github.com/mostafatalebi /ElementsLocator/blob/master/elements_locator.jquery.js
function element_mouse_is_inside (elementToBeChecked, mouseEvent, with_margin, offset_object)
{
if(!with_margin)
{
with_margin = false;
}
if(typeof offset_object !== 'object')
{
offset_object = {};
}
var elm_offset = elementToBeChecked.offset();
var element_width = elementToBeChecked.width();
element_width += parseInt(elementToBeChecked.css("padding-left").replace("px", ""));
element_width += parseInt(elementToBeChecked.css("padding-right").replace("px", ""));
var element_height = elementToBeChecked.height();
element_height += parseInt(elementToBeChecked.css("padding-top").replace("px", ""));
element_height += parseInt(elementToBeChecked.css("padding-bottom").replace("px", ""));
if( with_margin)
{
element_width += parseInt(elementToBeChecked.css("margin-left").replace("px", ""));
element_width += parseInt(elementToBeChecked.css("margin-right").replace("px", ""));
element_height += parseInt(elementToBeChecked.css("margin-top").replace("px", ""));
element_height += parseInt(elementToBeChecked.css("margin-bottom").replace("px", ""));
}
elm_offset.rightBorder = elm_offset.left+element_width;
elm_offset.bottomBorder = elm_offset.top+element_height;
if(offset_object.hasOwnProperty("top"))
{
elm_offset.top += parseInt(offset_object.top);
}
if(offset_object.hasOwnProperty("left"))
{
elm_offset.left += parseInt(offset_object.left);
}
if(offset_object.hasOwnProperty("bottom"))
{
elm_offset.bottomBorder += parseInt(offset_object.bottom);
}
if(offset_object.hasOwnProperty("right"))
{
elm_offset.rightBorder += parseInt(offset_object.right);
}
var mouseX = mouseEvent.pageX;
var mouseY = mouseEvent.pageY;
if( (mouseX > elm_offset.left && mouseX < elm_offset.rightBorder)
&& (mouseY > elm_offset.top && mouseY < elm_offset.bottomBorder) )
{
return true;
}
else
{
return false;
}
}
Как я не могу комментировать, поэтому я напишу это как ответ!
Пожалуйста, обратите внимание на разницу между css-селектором «: hover» и событием hover!
«: hover» является селектором css и действительно удалился с событием при его использовании $("#elementId").is(":hover")
, но в этом смысле это не имеет никакого отношения к зависанию события jQuery.
, если вы код $("#elementId:hover")
, элемент будет выбран только при наведении мыши. вышеприведенный оператор будет работать со всеми версиями jQuery, поскольку вы выбираете этот элемент с чистым и законным выбором css.
С другой стороны, наведение события, которое является
$("#elementId").hover(
function() {
doSomething();
}
);
, действительно отменено как jQuery 1.8 здесь состояние с сайта jQuery:
Когда используется имя события «hover», подсистема событий преобразует ее в «mouseenter mouseleave» в строке события. Это раздражает по нескольким причинам:
Семантика: зависание - это не то же самое, что вводить и оставлять элемент мыши, это означает некоторое замедление или задержку перед стрельбой. Название события: Event.type, возвращаемый прикрепленным обработчиком, не зависает, но либо с помощью мыши, либо с помощью мыши. Ни одно другое событие не делает этого. Сопоставление имени «hover»: невозможно связать событие с именем «hover» и запустить его с помощью .trigger («hover»). Документы уже назвали это имя «сильно обескураженным для нового кода», я хотел бы официально отказаться от него в версии 1.8 и в конечном итоге удалить его.
blockquote>Почему они удалили использование («: hover ») неясно, но хорошо, вы все равно можете использовать его, как указано выше, и вот немного взломать его до сих пор.
(function ($) { /** * :hover selector was removed from jQuery 1.8+ and cannot be used with .is(":hover") * but using it in this way it works as :hover is css selector! * **/ $.fn.isMouseOver = function() { return $(this).parent().find($(this).selector + ":hover").length > 0; }; })(jQuery);
О, и я бы не стал рекомендовать версию тайм-аута, поскольку это приносит много сложности, используйте таймаут-функции для такого рода вещей, если нет другого пути и поверьте мне, в 95% процентов всех случаев есть другой способ!
Надеюсь, я помогу пару людей там.
Greetz Andy
Я взял идею SLaks и завернул ее в маленький класс .
function HoverWatcher(selector){
this.hovering = false;
var self = this;
this.isHoveringOver = function() {
return self.hovering;
}
$(selector).hover(function() {
self.hovering = true;
}, function() {
self.hovering = false;
})
}
var box1Watcher = new HoverWatcher('#box1');
var box2Watcher = new HoverWatcher('#box2');
$('#container').click(function() {
alert("box1.hover = " + box1Watcher.isHoveringOver() +
", box2.hover = " + box2Watcher.isHoveringOver());
});
Вы можете использовать событие jQuery hover
для отслеживания вручную:
$(...).hover(
function() { $.data(this, 'hover', true); },
function() { $.data(this, 'hover', false); }
).data('hover', false);
if ($(something).data('hover'))
//Hovered!
JUST FYI для будущих искателей этого.
blockquote>Я создал плагин jQuery, который может это сделать и многое другое. В моем плагине, чтобы получить все элементы, курсор в настоящее время зависает, просто выполните следующее:
$.cursor("isHover"); // will return jQ object of all elements the cursor is // currently over & doesn't require timer
Как я уже упоминал, он также имеет много других применений, как вы можете видеть в jsFiddle найдено здесь
Спасибо вам обоим. В какой-то момент мне пришлось отказаться от попытки обнаружить, была ли мышь по-прежнему над элементом. Я знаю, что это возможно, но для этого может потребоваться слишком много кода.
Мне потребовалось немного времени, но я взял оба ваши предложения и придумал что-то, что сработало бы для меня.
Вот упрощенный (но функциональный) пример:
$("[HoverHelp]").hover (
function () {
var HelpID = "#" + $(this).attr("HoverHelp");
$(HelpID).css("top", $(this).position().top + 25);
$(HelpID).css("left", $(this).position().left);
$(HelpID).attr("fadeout", "false");
$(HelpID).fadeIn();
},
function () {
var HelpID = "#" + $(this).attr("HoverHelp");
$(HelpID).attr("fadeout", "true");
setTimeout(function() { if ($(HelpID).attr("fadeout") == "true") $(HelpID).fadeOut(); }, 100);
}
);
И затем, чтобы сделать эту работу над некоторым текстом, это все, что мне нужно сделать:
<div id="tip_TextHelp" style="display: none;">This help text will show up on a mouseover, and fade away 100 milliseconds after a mouseout.</div>
This is a <span class="Help" HoverHelp="tip_TextHelp">mouse over</span> effect.
Наряду с множеством фантазийных CSS это позволяет использовать некоторые очень приятные подсказки подсказки для мыши , Кстати, мне нужна была задержка в mouseout из-за крошечных промежутков между флажками и текстом, который заставлял мигать при перемещении мыши. Но это работает как прелесть. Я также сделал что-то подобное для событий focus / blur.
Вы можете проверить с помощью jQuery
, если какой-либо дочерний div имеет определенный класс. Затем, применяя этот класс, когда вы наводите указатель мыши на определенный div, вы можете проверить, находится ли над ним ваша мышь, даже если вы наведите указатель мыши на другой элемент на странице. Я использовал это, потому что у меня были пробелы между divs во всплывающем окне, и я только хотел закрыть всплывающее окно, когда я отошел от всплывающего окна, а не когда я наводил указатель мыши на пробелы во всплывающем окне. Таким образом, я вызвал функцию mouseover в div контента (что было всплывающее окно), но это вызовет только функцию закрытия, когда я перепутал содержимое div, и был вне всплывающего окна!
$(".pop-up").mouseover(function(e) { $(this).addClass("over"); }); $(".pop-up").mouseout(function(e) { $(this).removeClass("over"); }); $("#mainContent").mouseover(function(e){ if (!$(".expanded").hasClass("over")) { Drupal.dhtmlMenu.toggleMenu($(".expanded")); } });
В jQuery вы можете использовать .is (': hover'), поэтому
function IsMouseOver(oi)
{
return $(oi).is(':hover');
}
теперь будет самым кратким способом предоставления функции, запрошенной в OP.
Примечание. Вышеописанное не работает в IE8 или ниже
. Как менее лаконичная альтернатива, которая работает в IE8 (если я могу доверять модулю IE8 IE8), и делает это без запуска $(...).hover(...)
повсюду , и не требует знания селектора для элемента (в этом случае ответ Иво проще):
function IsMouseOver(oi)
{
return oi.length &&
oi.parent()
.find(':hover')
.filter(function(s){return oi[0]==this})
.length > 0;
}
Я объединил идеи из этой темы и придумал это, что полезно для отображения / скрытия подменю:
$("#menu_item_a").mouseenter(function(){
clearTimeout($(this).data('timeoutId'));
$("#submenu_a").fadeIn("fast");
}).mouseleave(function(){
var menu_item = $(this);
var timeoutId = setTimeout(function(){
if($('#submenu_a').is(':hover'))
{
clearTimeout(menu_item.data('timeoutId'));
}
else
{
$("#submenu_a").fadeOut("fast");
}
}, 650);
menu_item.data('timeoutId', timeoutId);
});
$("#submenu_a").mouseleave(function(){
$(this).fadeOut("fast");
});
Кажется, работает для меня. Надеюсь, это поможет кому-то.
EDIT: Теперь реализация этого подхода работает некорректно в IE.
Вы можете использовать is(':visible');
в jquery И для $ ('. item: hover') он также работает в JQuery.
это htm-код snnipet:
<li class="item-109 deeper parent">
<a class="root" href="/Comsopolis/index.php/matiers"><span>Matiers</span></a>
<ul>
<li class="item-110 noAff">
<a class=" item sousMenu" href="/Comsopolis/index.php/matiers/tsdi">
<span>Tsdi</span>
</a>
</li>
<li class="item-111 noAff">
<a class="item" href="/Comsopolis/index.php/matiers/reseaux">
<span>Réseaux</span>
</a>
</li>
</ul>
</li>
, и это код JS:
$('.menutop > li').hover(function() {//,.menutop li ul
$(this).find('ul').show('fast');
},function() {
if($(this).find('ul').is(':hover'))
$(this).hide('fast');
});
$('.root + ul').mouseleave(function() {
if($(this).is(':visible'))
$(this).hide('fast');
});
это то, о чем я говорил:)
ВНИМАНИЕ: is(':hover')
устарел в jquery 1.8+. См. этот пост для решения.
Вы также можете использовать этот ответ: https://stackoverflow.com/a/6035278/8843 для тестирования если мышь навевает элемент:
$('#test').click(function() {
if ($('#hello').is(':hover')) {
alert('hello');
}
});