javascript - mouseout olayı ile ilgili sorunlar


Bir resmi gizlemek ve altında gizlenmiş olan bazı metinleri göstermek için JavaScript kullanıyorum. Ama, metin gösterildiğinde üzerine kaydırdığınızda, konteyner üzerinde mouseout olayı tetikleniyor, bu da metni gizleyip resmi tekrar gösteriyor ve bir garip döngüye giriyor.

HTML şöyle görünüyor:

<div onmouseover="jsHoverIn('1')"
     onmouseout="jsHoverOut('1')">
    <div id="image1" />
    <div id="text1" style="display: none;">
        <p>some content</p>
        <p>some more content</p>
    </div>
</div>

Ve javascript (Scriptaculous kullanıyor):

function jsHoverIn(id) {
  if(!visible[id]) {
    new Effect.Fade ("image" + id, {queue: { position: 'end', scope: id } });
    new Effect.Appear ("text" + id, {queue: { position: 'end', scope: id } });
    visible[id] = true;
  }
}
function jsHoverOut (id) {
  var scope = Effect.Queues.get(id);
  scope.each(function(effect) { effect.cancel(); });

  new Effect.Fade ("text" + id, {queue: { position: 'end', scope: id } });
  new Effect.Appear ("image" + id, {queue: { position: 'end', scope: id } });
  visible[id] = false;
}

Bu gerçekten basit görünüyor, ama bunu anlayamıyorum bir türlü.

Cevap #1

Konteyner div'ine şunu verirdim:

position: relative;

ve kapsayıcıya üçüncü bir div ekle (kapsayıcının son çocuğu olmalı) ve şunlarla:

position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;

ve bunun yerine bu div üzerinde mouseover ve mouseout olaylarını yakala.

Çocuk elemanı olmadığı için, ona yayılacak yanlış mouseover ve mouseout olaylarını almamalısınız.

Düzenle:

İnanıyorum ki olan şey şudur: İmleç bir üst öğeden bir alt öğeye hareket ettiğinde, üst öğede bir mouseout olayı ve alt öğede bir mouseover olayı gerçekleşir. Ancak, alt öğedeki mouseover işleyicisi olayı yakalamaz ve yayılmasını durdurmazsa, üst öğe de mouseover olayını alacaktır.

Cevap #2

Görünüşe göre aslında istediğiniz şey mouseenter/mouseleave (IE'ye özgü olaylar, ama taklit etmesi kolay):

// Observe mouseEnterLeave on mouseover/mouseout
var mouseEnterLeave = function(e) {
    var rel = e.relatedTarget, cur = e.currentTarget;
    if (rel && rel.nodeType == 3) {
        rel = rel.parentNode;
    }
    if(
        // Outside window
        rel == undefined ||
        // Firefox/other XUL app chrome
        (rel.tagName && rel.tagName.match(/^xul\:/i)) ||
        // Some external element
        (rel && rel != cur && rel.descendantOf && !rel.descendantOf(cur))
    ) {
        e.currentTarget.fire('mouse:' + this, e);
        return;
    }
};
$(yourDiv).observe('mouseover', mouseEnterLeave.bind('enter'));
$(yourDiv).observe('mouseout', mouseEnterLeave.bind('leave'));

// Use mouse:enter and mouse:leave for your events
$(yourDiv).observe(!!Prototype.Browser.IE ? 'mouseenter' : 'mouse:enter', yourObserver);
$(yourDiv).observe(!!Prototype.Browser.IE ? 'mouseleave' : 'mouse:leave', yourObserver);

Alternatif olarak, prototype.js dosyasını yamanız ve mouseenter ve mouseleave olaylarını güvenle kullanmanız mümkündür. Pencereyi terk etme veya XUL chrome’a girme kontrolünü genişlettiğimi unutmayın; bu, benim için Firefox’ta bazı uç durumları düzeltmiş gibi görünüyor.