jQuery проверить, находится ли мышь над телом [дубликат]

Вы используете объект, содержащий ссылку нулевого значения. Таким образом, он дает пустое исключение. В примере строковое значение равно null, и при проверке его длины произошло исключение.

Пример:

string value = null;
if (value.Length == 0) // <-- Causes exception
{
    Console.WriteLine(value); // <-- Never reached
}

Ошибка исключения:

Необработанное исключение:

System.NullReferenceException: ссылка на объект не установлена ​​в экземпляр объекта. в Program.Main ()

247
задан Steve Wortham 13 August 2009 в 19:02
поделиться

23 ответа

Установите тайм-аут в мыши, чтобы затухать и сохранить возвращаемое значение для данных в объекте. Затем, onmouseover, отмените таймаут, если в данных есть значение.

Удалите данные при обратном вызове fadeout.

На самом деле дешевле использовать mouseenter / mouseleave, потому что они не стреляйте в меню при стрельбе по мыши / мыши.

96
ответ дан happytime harry 4 September 2018 в 08:04
поделиться

Вот техника, которая не полагается на 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');
2
ответ дан Andrew Newdigate 4 September 2018 в 08:04
поделиться

Расширяясь от того, что сказал Happytime harry, обязательно используйте функцию .data () jquery для хранения идентификатора таймаута. Это так, что вы можете легко получить идентификатор таймаута, когда «mouseenter» запускается на этом же элементе позже, что позволяет вам исключить запуск триггера для вашей всплывающей подсказки.

0
ответ дан Arthur Goldsmith 4 September 2018 в 08:04
поделиться

Я ответил на это в другом вопросе со всеми подробностями, которые могут вам понадобиться:

Обнаруживать 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.

261
ответ дан Community 4 September 2018 в 08:04
поделиться
  • 1
    Старый пост, но прямо на $$$ ... Хорошая работа Артура! – happytime harry 19 November 2010 в 18:32
  • 2
    Вы спасатель жизни. – Conrad.Dean 4 January 2012 в 19:05
  • 3
    Фантастическое решение, отличная работа. – Codex73 15 February 2012 в 01:35
  • 4
    Удивительная, отличная идея. – James Skidmore 20 March 2012 в 20:02
  • 5
    Это, безусловно, самое лучшее! Короткие и сладкие! – Serj Sagan 29 March 2012 в 12:48
  • 6
    Это не документировано нигде (afik) и не кажется точным с динамически отображаемыми элементами (например, меню). – lambinator 30 March 2012 в 18:06
  • 7
    это не работает в ie8 и down. – Peter Lada 19 June 2012 в 18:52
  • 8
    -1 из-за этого устаревшего в 1.8+ – Shyam Habarakada 9 April 2013 в 23:23
  • 9
    сломанный как jQuery 1.9.1 !! вместо этого используйте решение Ivo – mathheadinclouds 11 May 2013 в 21:52
  • 10
    Хотелось бы, чтобы я обыскал это раньше, Просто потратил 3 часа на пробную версию и ошибку. Это идеальное решение. Работает как шарм даже через 7 лет: D – Surjith S M 13 March 2016 в 11:03

Я вижу, что таймауты используются для этого много, но в контексте события вы не можете посмотреть на координаты, например:

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: это хорошая идея, но не работают достаточно последовательно. Возможно, с небольшими ухищрениями.

2
ответ дан dlo 4 September 2018 в 08:04
поделиться

Я не мог использовать ни одно из приведенных выше предложений. Почему я предпочитаю свое решение? Этот метод проверяет, находится ли мышь над элементом в любое время, выбранным вами. 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");
    }
});
0
ответ дан Hyper Motion 4 September 2018 в 08:04
поделиться

Мне было нужно что-то точно, как это (в немного более сложной среде, и решение с большим количеством «мышь» и «мышь» не работало должным образом), поэтому я создал небольшой плагин 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 и работает нормально.

24
ответ дан Ivan Castellanos 4 September 2018 в 08:04
поделиться
  • 1
    Решение не работает, если элемент является iframe. Поскольку событие mousemove не срабатывает над iframe, а Mouse Последняя Позиция не обновляется. – Gabriel Diaconescu 2 April 2012 в 13:39
  • 2
    Исправлена! Теперь он должен работать с элементами iframe и даже с элементами внутри iframe (но только если они находятся в одном домене) – Ivan Castellanos 5 April 2012 в 21:06
  • 3
    Отлично работает для меня. Спасибо! – Man Personson 18 July 2012 в 20:48
  • 4
    Он, похоже, не работает на mouseenter (Chrome) - codepen.io/anon/pen/kcypB – wrygiel 8 November 2013 в 13:59
  • 5
    – Alexander Dixon 26 August 2015 в 23:23

Чистая и элегантная проверка наведения:

if ($('#element:hover').length != 0) {
    // do something ;)
}
203
ответ дан Ivo 4 September 2018 в 08:04
поделиться

Просто примечание об популярном и полезном ответе Артура Голдсмита выше: если вы перемещаете мышь из одного элемента в другой в IE (по крайней мере до IE 9), у вас могут возникнуть проблемы с тем, чтобы это правильно работало, если новый элемент имеет прозрачный фон (который он по умолчанию). Моим обходным путем явился новый элемент прозрачного фонового изображения.

0
ответ дан Jish 4 September 2018 в 08:04
поделиться

Это был бы самый простой способ сделать это!

  function(oi) 
  {
   if(!$(oi).is(':hover')){$(oi).fadeOut(100);}
  }
2
ответ дан Kareem 4 September 2018 в 08:04
поделиться

Вы можете использовать события mousePoint и mouseleave jQuery. Вы можете установить флаг, когда мышь входит в нужную область, и удалите флаг, когда он покинет область.

0
ответ дан mikerobi 4 September 2018 в 08:04
поделиться

Вот функция, которая помогает вам проверить, находится ли мышь внутри элемента или нет. Единственное, что вам нужно сделать, - это вызвать функцию, в которой вы можете связать объект 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;
    }
}
0
ответ дан Mostafa Talebi 4 September 2018 в 08:04
поделиться

Как я не могу комментировать, поэтому я напишу это как ответ!

Пожалуйста, обратите внимание на разницу между 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 и в конечном итоге удалить его.

Почему они удалили использование («: 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

3
ответ дан Phenix 4 September 2018 в 08:04
поделиться

Я взял идею 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());
});
7
ответ дан ripper234 4 September 2018 в 08:04
поделиться

Вы можете использовать событие jQuery hover для отслеживания вручную:

$(...).hover(
    function() { $.data(this, 'hover', true); },
    function() { $.data(this, 'hover', false); }
).data('hover', false);

if ($(something).data('hover'))
    //Hovered!
34
ответ дан SLaks 4 September 2018 в 08:04
поделиться

JUST FYI для будущих искателей этого.

Я создал плагин jQuery, который может это сделать и многое другое. В моем плагине, чтобы получить все элементы, курсор в настоящее время зависает, просто выполните следующее:

$.cursor("isHover"); // will return jQ object of all elements the cursor is 
                     // currently over & doesn't require timer

Как я уже упоминал, он также имеет много других применений, как вы можете видеть в jsFiddle найдено здесь

6
ответ дан SpYk3HH 4 September 2018 в 08:04
поделиться

Спасибо вам обоим. В какой-то момент мне пришлось отказаться от попытки обнаружить, была ли мышь по-прежнему над элементом. Я знаю, что это возможно, но для этого может потребоваться слишком много кода.

Мне потребовалось немного времени, но я взял оба ваши предложения и придумал что-то, что сработало бы для меня.

Вот упрощенный (но функциональный) пример:

$("[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.

2
ответ дан Steve Wortham 4 September 2018 в 08:04
поделиться

Вы можете проверить с помощью 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"));
        }
    });

2
ответ дан Taryn 4 September 2018 в 08:04
поделиться

В 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;
}
10
ответ дан towr 4 September 2018 в 08:04
поделиться
  • 1
    Это недопустимый селектор jQuery! Люди должны прекратить предлагать этот метод. Это везде и несовместимо с IE8. – Sanne 19 February 2014 в 14:46
  • 2
    См. Мой другой ответ, чтобы иметь решение для IE8 – Sanne 19 February 2014 в 15:23
  • 3

Я объединил идеи из этой темы и придумал это, что полезно для отображения / скрытия подменю:

$("#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.

0
ответ дан Two Piers 4 September 2018 в 08:04
поделиться

Вы можете использовать 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');

});

это то, о чем я говорил:)

-1
ответ дан ucefkh 4 September 2018 в 08:04
поделиться
  • 1
    Я не вижу, как это связано с вопросом. – Andrew Barber 12 February 2013 в 00:03
  • 2
    вы можете использовать это, когда вы выходите из мыши и показываете свой скрытый элемент, и после задержки вы можете проверить, видно ли это, когда мышь вводит целевой элемент, который вы хотите скрыть / показать – ucefkh 12 February 2013 в 00:12
  • 3
    Я не думаю, что вы хорошо прочитали этот вопрос. Это совсем не то, что ему нужно. – Andrew Barber 12 February 2013 в 00:13
  • 4
    нет, я сейчас делаю выпадающее меню с jquery. – ucefkh 12 February 2013 в 00:17
  • 5
    Что делать вы не связаны с этим вопросом . (по всей видимости( – Andrew Barber 12 February 2013 в 00:18
$(document).hover(function(e) {
    alert(e.type === 'mouseenter' ? 'enter' : 'leave');
});

FIDDLE

0
ответ дан yckart 4 September 2018 в 08:04
поделиться

ВНИМАНИЕ: is(':hover') устарел в jquery 1.8+. См. этот пост для решения.

Вы также можете использовать этот ответ: https://stackoverflow.com/a/6035278/8843 для тестирования если мышь навевает элемент:

$('#test').click(function() {
    if ($('#hello').is(':hover')) {
        alert('hello');
    }
});
261
ответ дан Community 4 September 2018 в 08:04
поделиться
  • 1
    Старый пост, но прямо на $$$ ... Хорошая работа Артура! – happytime harry 19 November 2010 в 18:32
  • 2
    Вы спасатель жизни. – Conrad.Dean 4 January 2012 в 19:05
  • 3
  • 4
    Удивительная, отличная идея. – James Skidmore 20 March 2012 в 20:02
  • 5
    Это, безусловно, самое лучшее! Короткие и сладкие! – Serj Sagan 29 March 2012 в 12:48
  • 6
    Это не документировано нигде (afik) и не кажется точным с динамически отображаемыми элементами (например, меню). – lambinator 30 March 2012 в 18:06
  • 7
    это не работает в ie8 и down. – Peter Lada 19 June 2012 в 18:52
  • 8
    -1 из-за этого устаревшего в 1.8+ – Shyam Habarakada 9 April 2013 в 23:23
  • 9
    сломанный как jQuery 1.9.1 !! вместо этого используйте решение Ivo – mathheadinclouds 11 May 2013 в 21:52
  • 10
    Хотелось бы, чтобы я обыскал это раньше, Просто потратил 3 часа на пробную версию и ошибку. Это идеальное решение. Работает как шарм даже через 7 лет: D – Surjith S M 13 March 2016 в 11:03
Другие вопросы по тегам:

Похожие вопросы: