Alt öğeler tarafından tetiklenen mouseout olayları nasıl devre dışı bırakılır?


107

Sorunu ayrıntılı olarak anlatmama izin verin:

Bir öğenin üzerine geldiğimde mutlak konumlandırılmış bir div göstermek istiyorum. JQuery ile bu gerçekten basit ve gayet iyi çalışıyor. Ancak fare alt öğelerden birinin üzerine geldiğinde, içeren div öğesinin mouseout olayını tetikler. Bir alt öğenin üzerine gelindiğinde javascript'in içeren öğenin mouseout olayını tetiklemesini nasıl engelleyebilirim?

Bunu jQuery ile yapmanın en iyi ve en kısa yolu nedir?

İşte ne demek istediğimi açıklamak için basitleştirilmiş bir örnek:

Html:

<a>Hover Me</a>
<div>
  <input>Test</input>
  <select>
    <option>Option 1</option>
    <option>Option 2</option>
  </select>
</div>

Javascript / jQuery:

$('a').hover( function() { $(this).next().show() }
              function() { $(this).next().hide() } );

Yanıtlar:


209

Soru biraz eski ama geçen gün bununla karşılaştım.

JQuery son sürümleri ile Bunu yapmanın en kolay yolu kullanmaktır mouseenterve mouseleaveyerine olayları mouseovervemouseout .

Davranışı hızlı bir şekilde test edebilirsiniz:

$(".myClass").on( {
   'mouseenter':function() { console.log("enter"); },
   'mouseleave':function() { console.log("leave"); }
});

4
Jquery olmayan javascript ile ilgili sorunuma yardımcı oldu. Olay dinleyicilerimle mouseleave yerine mouseenter / mouseout kullanıyordum!
Jo E.

1
Arama uğruna, bu fare olay davranışları AS3'e eşdeğerdir ROLL_OVERve ROLL_OUTAS3'tür.
Jeff Ward

2
Beni biraz baş ağrısından kurtardı. Alt öğelerin üzerine gelmenin üst öğenin mouseoutetkinliğini tetiklemesi tuhaftır , ancak aslında olay hala ana öğenin içindeyken.
javiniar.leonard

18

Basitlik uğruna, yeni görüntülenen içeriği fareyle üzerine gelme olayının bağlı olduğu öğenin içine koymak için html'yi biraz yeniden düzenlerdim:

<div id="hoverable">
  <a>Hover Me</a>
  <div style="display:none;">
    <input>Test</input>
    <select>
      <option>Option 1</option>
      <option>Option 2</option>
    </select>
  </div>
</div>

O zaman şöyle bir şey yapabilirsiniz:

$('#hoverable').hover( function() { $(this).find("div").show(); },
                       function() { $(this).find("div").hide(); } );

Not: Satır içi css'i önermiyorum, ancak bu, örneğin sindirilmesini kolaylaştırmak için yapıldı.


Bu gerçekten çok basit ve temiz bir çözüm. Bana hatırlattığın için teşekkürler. Ama benim özel durumumda, ki bu tam olarak sorudaki gibi değil, bu bir seçenek değil. Yine de teşekkürler!
Sander Versluys

SO'da başkaları tarafından anlatılan farklı yöntemleri denedikten sonra, yönteminize geri döndüm ve benim durumumda çalışmasını sağladım. Yaşasın! :-)
Sander Versluys

11

Evet çocuklar, .mouseleavebunun yerine şunu kullanın .mouseout:

$('div.sort-selector').mouseleave(function() {
    $(this).hide();
});

Veya şunlarla birlikte kullanın live:

$('div.sort-selector').live('mouseleave', function() {
    $(this).hide();
});

8

Javascript'in önleme olayı köpürmesini engelleyen jQuery eşdeğerini arıyorsunuz.

Şuna bir bak:

http://docs.jquery.com/Events/jQuery.Event#event.stopPropagation.28.29

Temel olarak, alt DOM düğümlerinde olayı yakalamanız ve orada bunların DOM ağacında yayılmasını durdurmanız gerekir. Başka bir yol, gerçekten önerilmese de (sayfanızdaki mevcut olaylarla ciddi şekilde karışabileceğinden), olay yakalamayı sayfadaki belirli bir öğeye ayarlamaktır ve tüm olayları alacaktır. Bu, DnD davranışı ve benzeri için kullanışlıdır, ancak kesinlikle sizin durumunuz için değildir.


bu olması gerektiği gibi çalışıyor, neden çalıştıramadığınızı bilmiyorum .. sadece bir bilgi, dokümanlar için bir bağlantı değişti, yeni bağlantı docs.jquery.com/Events/jQuery.Event#event.stopPropagation. 28.29
zappan

3

Ben sadece fare koordinatlarının mouseout olayındaki öğenin dışında olup olmadığını kontrol ediyorum.

İşe yarıyor ama bu kadar basit bir şey için çok fazla kod var :(

function mouseOut(e)
{
    var pos = GetMousePositionInElement(e, element);
    if (pos.x < 0 || pos.x >= element.size.X || pos.y < 0 || pos.y >= element.size.Y)
    {
        RealMouseOut();
    }
    else
    {
         //Hit a child-element
    }
}

Okunabilirlik için kod kesilir, kutudan çıkar çıkmaz.


1

Ryan'a katılıyorum.

Sizin sorununuz, "next" div'in A'nın "alt öğesi" olmamasıdır. HTML veya jQuery'nin "a" öğenizin DOM'daki alt div ile ilişkili olduğunu bilmesinin bir yolu yoktur. Bunları sarmak ve paketleyiciye bir imleci koymak, ilişkili oldukları anlamına gelir.

Bununla birlikte, kodunun en iyi uygulamalara uygun olmadığını lütfen unutmayın. Gizli stili öğeler üzerinde satır içi olarak ayarlamayın; kullanıcının CSS'si varsa ancak javascript yoksa, öğe gizlenir ve gösterilemez. Daha iyi uygulama, bu beyanı belgeye koymaktır. Hazır olay.


Deriyi document.ready olaya koymakla tamamen aynı fikirdeyim. Satır içi css, tam bir çalışma örneğini mümkün olan en basit şekilde iletmek içindi. Bunu netleştirmek için yanıtımı düzenleyeceğim.
Ryan McGeary

1

Bu sorunu pointer-events: none;alt öğelerime css ekleyerek çözdüm


Bu, bazı eski kodların fareyle üzerine gelme ve fare bırakma etkinlikleriyle kendi açılır pencerelerini oluştururken düzelmesine gerçekten çok yardımcı oldu
CM

0

Bunu genellikle gördüğüm yol, fareyi HoverMe öğesinden hareket ettirme arasında yaklaşık 1/2 saniye gecikme olması. Fareyi üzerine getirilen öğeye hareket ettirirken, öğenin üzerine geldiğinizi gösteren bazı değişkenler ayarlamak ve ardından temelde bu değişken ayarlanmışsa, fareyle üzerine gelinen kısmın gizlenmesini durdurmak isteyeceksiniz. Daha sonra, fareyi çıkardığınızda kaybolması için benzer bir gizleme işlevi OnMouseOut üzerine getirilmiş öğeden eklemeniz gerekir. Maalesef size herhangi bir kod veya daha somut bir şey veremem, ancak umarım bu sizi doğru yönü gösterir.


Evet idd Ben de öyle bir çözüm uyguladım. Bu gerçekten yaygın bir sorundur. Başka hangi çözüm olduğunu gerçekten merak ediyorum ... Cevabınız için teşekkürler!
Sander Versluys

0

Bu eski bir soru, ama asla eskimez. Doğru cevap, bytebrite ile verilen cevap olmalıdır .

Sadece mouseover / mouseout ile mouseenter / mouseleave arasındaki farkı belirtmek istiyorum. Burada harika ve faydalı bir açıklama okuyabilirsiniz (çalışan bir demo için sayfanın en altına gidin). Kullandığınızda mouseout, fare bir alt öğe olsa bile başka bir öğeye girdiğinde olay durur. Öte yandan, kullandığınızda mouseleave, fare bir alt öğenin üzerine geldiğinde olay tetiklenmez ve bu, OP'nin elde etmek istediği davranıştır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.