كيف يمكنني التحقق مما إذا كان الماوس أكثر من عنصر في JQUERY؟

StackOverflow https://stackoverflow.com/questions/1273566

  •  16-09-2019
  •  | 
  •  

سؤال

هل هناك طريقة سريعة وسهلة للقيام بذلك في jquery التي أفتقدها؟

لا أريد استخدام حدث Mouseover لأنني أستخدمه بالفعل لشيء آخر. أحتاج فقط إلى معرفة ما إذا كان الماوس أكثر من عنصر في لحظة معينة.

أود أن أفعل شيئا كهذا، إذا كان هناك وظيفة "ISMOUSEOVER"

function hideTip(oi) {
    setTimeout(function() { if (!IsMouseOver(oi)) $(oi).fadeOut(); }, 100);
}
هل كانت مفيدة؟

المحلول

حدد مهلة على Mouseout إلى Fadeout وتخزين قيمة الإرجاع إلى البيانات في الكائن. ثم onmouseover، قم بإلغاء المهلة إذا كانت هناك قيمة في البيانات.

أخرج البيانات عن رد الاتصال.

إنه في الواقع أقل تكلفة لاستخدام Mouseenter / Mouseelive لأنهم لا يطلقون النار في القائمة عند حريق الأطفال Mouseout / Mouseout.

نصائح أخرى

يوضح هذا الرمز ما هابي هاري وأنا أحاول أن أقول. عندما يدخل الماوس، يخرج تلميح الأدوات، عندما يترك الماوس يضع تأخيرا لذلك تختفي. إذا دخول الماوس إلى نفس العنصر قبل الناتج عن التأخير، فإننا ندمر الزناد قبل إطفاء البيانات التي تخزنها من قبل.

$("someelement").mouseenter(function(){
    clearTimeout($(this).data('timeoutId'));
    $(this).find(".tooltip").fadeIn("slow");
}).mouseleave(function(){
    var someElement = $(this),
        timeoutId = setTimeout(function(){
            someElement.find(".tooltip").fadeOut("slow");
        }, 650);
    //set the timeoutId, allowing us to clear this trigger if the mouse comes back over
    someElement.data('timeoutId', timeoutId); 
});

فحص مروم نظيف وأنيق:

if ($('#element:hover').length != 0) {
    // do something ;)
}

تحذير: is(':hover') تم إهمالها في مسج 1.8+. يرى هذا المشنور للحل.

يمكنك أيضا استخدام هذه الإجابة: https://stackoverflow.com/a/6035278/8843. لاختبار ما إذا كان الماوس يحوم عنصر:

$('#test').click(function() {
    if ($('#hello').is(':hover')) {
        alert('hello');
    }
});

يمكنك استخدام jQuery's hover الحدث لتتبع يدويا:

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

if ($(something).data('hover'))
    //Hovered!

كنت بحاجة إلى شيء بالضبط مثل هذا (في بيئة أكثر تعقيدا قليلا والحل مع الكثير من "الفأرة" و "mouseleaves" لم يعمل بشكل صحيح) لذلك قمت بإنشاء مسافة مسج صغيرة تضيف الطريقة 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);

ثم في أي مكان من المستند، اتصل به مثل هذا ويعود صحيحا أو خطأ:

$("#player").ismouseover()

اختبرته على IE7 +، كروم 1+ و Firefox 4 ويعمل بشكل صحيح.

في JQuery، يمكنك استخدامها .is (': hover')، لذلك

function IsMouseOver(oi)
{
   return $(oi).is(':hover');
}

ستكون الآن الطريقة الأكثر إيجاز لتوفير الوظيفة المطلوبة في المرجع.

ملاحظة: ما سبق لا يعمل في IE8 أو أقل

بديل أقل شيوعا يعمل في IE8 (إذا استطعت أن أثق ب IE8 IE8 Modus)، فهل من دون التغاضي $(...).hover(...) في كل مكان، ولا يتطلب معرفة محدد للعنصر (في هذه الحالة هو إجابة IVO أسهل):

function IsMouseOver(oi)
{
    return oi.length && 
           oi.parent()
             .find(':hover')
             .filter(function(s){return oi[0]==this})
             .length > 0;
}

أخذت فكرة سلاغة وفصلها في فئة صغيرة.

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());
});

فقط FYI للمصدرين في المستقبل من هذا.

أنا جعلت مسافة مسج يمكن أن تفعل هذا وأكثر من ذلك بكثير. في البرنامج المساعد الخاص بي، للحصول على جميع العناصر التي يتم فيها تحليق المؤشر حاليا، ما عليك سوى القيام بما يلي:

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

كما ذكرت، كما أن لديها أيضا الكثير من الاستخدامات الأخرى كما ترون في

وجدت jsfiddle هنا

كما لا أستطيع التعليق، لذلك سأكتب هذا كإجابة!

يرجى فهم الفرق بين محدد CSS ": تحوم" وحدث التحويم!

": مروم" هو محدد CSS وإزالته بالفعل مع الحدث عند استخدامه مثل هذا $("#elementId").is(":hover"), ، لكن في أنه مما يعني أنه لا علاقة له بحدث مسج.

إذا كنت رمز $("#elementId:hover"), ، سيتم تحديد العنصر فقط عند تحريك الماوس. سيعمل البيان أعلاه مع جميع الإصدارات المستقية مثل اختيار هذا العنصر الخاص بك مع اختيار CSS النقي والأشرطة.

من ناحية أخرى الحدث تحوم ما هو

$("#elementId").hover(
     function() { 
         doSomething(); 
     }
); 

تم استبداله بالفعل باسم JQuery 1.8 هنا الدولة من موقع JQuery:

عند استخدام اسم الحدث "Hover"، يقوم النظام الفرعي للحدث بتحويله إلى "Mouseenter Mouseave" في سلسلة الأحداث. هذا مزعج لعدة أسباب:

دلالات: تحوم ليس هو نفسه يدخل الماوس وترك عنصر، فإنه يعني بعض المباراة من التباطؤ أو التأخير قبل إطلاق النار. اسم الحدث: الحدث.type الذي تم إرجاعه بواسطة المعالج المرفقة لا يحوم، ولكن إما Mouseenter أو Mouseave. لا يوجد حدث آخر يفعل هذا. شارك في اختيار اسم "Hover": من الممكن إرفاق حدث باسم "تحوم" وإطلاق النار عليه باستخدام. يقوم المستندات بالفعل بالاتصال بهذا الاسم "مثبطا بشدة للحصول على رمز جديد"، أود أن تنفجره رسميا لمدة 1.8 وفي النهاية أخرجه.

لماذا أزالوا الاستخدام (": تحوم") غير واضح ولكن حسنا، لا يزال بإمكانك استخدامه كما هو الحال أعلاه وهنا اختراق صغير لا يزال يستخدمه.

(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٪ في المئة من جميع الحالات هناك طريقة أخرى!

آمل أن أتمكن من مساعدة زوجين هناك.

تحية اندي

بفضل كل واحد منكما. في مرحلة ما، اضطررت إلى التخلي عن محاولة الكشف عن ما إذا كان الماوس لا يزال عبر العنصر. أعلم أنه من الممكن، ولكن قد يتطلب الكثير من التعليمات البرمجية لإنجازها.

استغرق الأمر مني بعض الشيء، لكنني أخذت من اقتراحاتك وتوصلت إلى شيء من شأنه أن يعمل بالنسبة لي.

إليك مثال مبسط (ولكن وظيفي):

$("[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 بسبب الثغرات الصغيرة بين مربعات الاختيار والنص الذي يسبب المساعدة في فلاش أثناء تحريك الماوس عبر. ولكن هذا يعمل مثل سحر. أنا أيضا فعلت شيئا مشابها لأحداث التركيز / طمس.

أرى مهلة تستخدم لهذا كثيرا، ولكن في سياق الحدث، لا يمكنك أن تنظر إلى الإحداثيات، مثل هذا؟:

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);
}

اعتمادا على السياق، قد تحتاج إلى التأكد من ذلك (هذا == E.Target) قبل الاتصال arexyinside (E).

Fyi - أنا أتطلع إلى استخدام هذا النهج داخل معالج Dragleave، من أجل تأكيد أن يحدث حدث Dragleave عن طريق الدخول إلى عنصر طفل. إذا كنت لا تحقق بطريقة أو بأخرى من أنك لا تزال داخل العنصر الأصل، فقد تتخذ عن طريق الخطأ اتخاذ إجراءات مخصصة فقط عندما تغادر الوالد حقا.

تحرير: هذه فكرة جميلة، لكنها لا تعمل باستمرار بما فيه الكفاية. ربما مع بعض القرص الصغيرة.

يمكنك اختبار مع jQuery إذا كان أي طفل فحم لديه فئة معينة. ثم من خلال تطبيق هذه الفئة عند الخروج من الفأرة وفقط DIV بعض، يمكنك اختبار ما إذا كان الماوس الخاص بك قد انتهى، حتى عند استخدام الماوس فوق عنصر مختلف في الصفحة أقل رمز بكثير بهذه الطريقة. لقد استخدمت هذا لأنني كان لدي مسافات بين Divs في نافذة منبثقة، وأردت فقط إغلاق المنبثقة عندما انتقلت من السطح، وليس عندما كنت نقل الماوس فوق المسافات الموجودة في المنبثقة. لذلك اتصلت بوظيفة Mouseover على المحتوى DIV (الذي انتهى منبثقة المنبثقة)، لكنه سيؤدي فقط إلى الوظيفة الوثيقة عندما قمت بفجيله على المحتوى DIV، وكان خارج المنبثقة!

$ (". المنبثقة"). Mouseover (وظيفة (E) {$ (this) .adverclass ("Over")؛})؛ $ (". المنبثقة"). Mouseout (وظيفة (E) {$ (this) .removeclass ("انتهى")؛})؛ $ ("# Maincontent"). Mouseover (وظيفة (E) {IF (! $ (". توسيع"). hasclass ("Over")) {drupal.dhtmlmenu.togglemenu.togglemenu ($ (". توسيع"))؛} })؛

سيكون هذا أسهل طريقة للقيام بذلك!

  function(oi) 
  {
   if(!$(oi).is(':hover')){$(oi).fadeOut(100);}
  }

إليك تقنية لا تعتمد على مسج وتستخدم دوم الأصلي matches api.. وبعد يستخدم بادئة البائع لدعم المتصفحات التي تعود إلى IE9. يرى Matchesselector على Caniuse.com. للحصول على التفاصيل الكاملة.

أولا إنشاء وظيفة Matchesslector، مثل ذلك:

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');

لقد أجبت على هذا في سؤال آخر، مع كل التفاصيل التي قد تحتاجها:

كشف إذا تحوم على عنصر مع جيس (لديه 99 upvotes في وقت كتابة هذا التقرير)

أساسا، يمكنك أن تفعل شيئا مثل:

var ishovered = oi.is(":hover");

هذا يعمل فقط إذا oi هو كائن مسج يحتوي على عنصر واحد. إذا كان هناك العديد من العناصر المتطابقة، تحتاج إلى تطبيقها على كل عنصر، على سبيل المثال:

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.

تمديد ما قاله "Happytime Harry"، تأكد من استخدام وظيفة JQuery .Data () لتخزين معرف المهلة. هذا بحيث يمكنك استرداد معرف المهلة بسهولة شديدة عندما يتم تشغيل "Mouseenter" في نفس العنصر في وقت لاحق، مما يتيح لك القضاء على الزناد لتخفيف تلميح الأدوات الخاص بك.

يمكنك استخدام أحداث JQuery's Mouseenter و Mouseeleave. يمكنك تعيين علامة عندما يدخل الماوس المنطقة المطلوبة وإخلاص العلم عندما يترك المنطقة.

كنت مجتمعا بالأفكار من هذا الموضوع وتوصلت إلى هذا، وهو مفيد لإظهار / إخفاء القائمة الفرعية:

$("#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");
 });

يبدو أن العمل بالنسبة لي. أمل أن هذا يساعد شخصاما.

تحرير: الآن إدراك هذا النهج لا يعمل بشكل صحيح في IE.

لم أستطع استخدام أي من الاقتراحات أعلاه.
لماذا أفضل الحل الخاص بي؟
هذه الطريقة يتحقق إذا كان الماوس أكثر من عنصر في في أي وقت تم اختياره بواسطتك.
mouseenter. و :يحوم تكون باردة، لكن Mouseenter تؤدي فقط إذا قمت بنقل الماوس، وليس عندما يتحرك العنصر تحت الماوس.
: تحوم حلوة جميلة ولكن ... أي

لذلك أفعل هذا:

لا 1. تخزين الماوس X، موضع y في كل مرة يتم نقله عند الحاجة إليه،
رقم 2. تحقق مما إذا كان الماوس فوق أي من العناصر التي تتطابق مع الاستعلام هل الاشياء ... مثل Trigger حدث 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");
    }
});

مجرد ملاحظة حول إجابة Arthur Goldsmith الشائعة ومفيدة من Arthur Godsmith أعلاه: إذا كنت تقوم بنقل الماوس من عنصر إلى آخر في IE (على الأقل حتى 9) قد تواجه مشكلة في الحصول على هذا للعمل بشكل صحيح إذا كان العنصر الجديد خلفية شفافة (التي ستفتقر إليها افتراضيا). كان الحلواني هو إعطاء العنصر الجديد صورة خلفية شفافة.

$(document).hover(function(e) {
    alert(e.type === 'mouseenter' ? 'enter' : 'leave');
});

كمان

فيما يلي وظيفة تساعدك على التحقق مما إذا كان الماوس داخل عنصر أم لا. الشيء الوحيد الذي يجب عليك فعله هو استدعاء الوظيفة حيث يمكنك الحصول على EventObject المرتبط بالماوس الحية. شيء من هذا القبيل:

$("body").mousemove(function(event){
     element_mouse_is_inside($("#mycontainer", event, true, {});
});

يمكنك رؤية الكود المصدري هنا في جيثب أو في أسفل المنشور:

https://github.com/mostafatalebi/elementlocator/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;
    }
}

يمكنك استخدام is(':visible'); في jQuery و for $ ('. البند: تحوم ") يعمل في مسج أيضا.

هذا هو رمز 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');

});

هذا ما كنت أتحدث عنه :)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top