2012-05-22 6 views
5

Araç ipucunu tetikleyen bir mouseover olayı var; Bu araç ipucunun, fare çıkarıldığında gitmesini istiyorum. onmouseout, eleman kaybolduğunda hariç çalışır. Benim fare artık, ben click "Bana Kaldır" zaman:onmouseout öğe kaybolduğunda tetiklenmiyor

<div id="bar"> 
    <div onmouseover="document.bgColor='gray'" onmouseout="document.bgColor='white'" style="border:1px solid black;"> 
    <span onclick="document.getElementById('bar').innerHTML = ''">Remove me</span> 
    </div> 
</div> 

sorun şudur: Burada

(böylece kolayca çalıştırabilirsiniz) yerine araç ipuçları değiştiren arka plan kullanan bir distile örnektir div üzerinde "bitti", ama onmouseout tetiklemiyor, çünkü o gitti. İstediğim şey, "Beni kaldır" ı tıklattığımda bu örnek için beyaz arkaplana dönmektir.

Kaçınılması gereken bariz bir çözüm var. Belgeyi el ile "düzeltmek" için öğeyi kaldıran onclick işleyicisini istemiyorum. Bunun nedeni, keyfi bir şekilde çok sayıda işleyicinin olabileceği ve bu sayede divun onmouseout ile ortadan kaldırılabileceği düşünülmektedir. Genel olarak, tüm mouseout ve kaldırma işleyicileri dinamik olarak oluşturulabilir ve birbirlerini tanımalıdır. İşleri daha da karmaşık hale getirmek için, çıkarılabilir elemanların birbirinin içine yerleştirildiği ve herhangi birinin çıkarılabileceği bir durumum olabilir. (Bu kısıtlamayı kaldırmak mümkün olabilir, ama biraz uğraşmanız gerekecektir.) Burada


işe yarayabilir bir çözümün bir örnek: Fareyle üzerine gelindiğinde, "aktif" olarak modal diyalog kayıt; daha sonra elemanlar her kaldırıldığında, tüm modal diyalogları yineleyin ve artık belgede olmayanları arayın. Ancak bu, global bir diyalog deposunu tutmamı ve zamanın aktif bir diyalog olduğunu ve n'nin diyaloğun DOM içinde ne kadar derinlemesine iç içe geçmiş olduğu zamanını (O * n) gerektiriyor. Ayrıca, hiçbir şey etkilenmemiş olsa bile, öğeleri kaldırdığımda bu işlemi çalıştırmam gerekiyor.

Çalışabileceğiniz başka bir çözüm: eğer bir onremovedfromdocument olayı uygularsanız, onremeoed işleyicisini onremovedfromdocument olayı olarak kopyalarız ve örnek de doğru şekilde çalışır. (JQuery'nin bunu destekleyebileceğini duyuyorum, ancak jQuery olmayan bir kodla birlikte çalışmam gerekiyor.)

İşte yine başka bir çözüm: her modal diyalogun, üst öğenin belgede olup olmadığını görmek için tekrar tekrar yoklamasını sağlayın. Olmadığı zaman, seppuku yapsın. Fakat oylama gerçekten çirkin. (Sanırım daha iyi bir şey yoksa bunu yapmaya istekli olurum!)

İşte başka bir fikir: onmouseout öğesinin önce tıklama öğesini yakalamasına izin vermek için olay yakalama özelliğini kullanın ve yine de olup olmadığını kontrol etmek için bir zamanlayıcı ayarlayın. tıklama yapıldıktan sonra belgede. Karmaşık bir ağaç yapısını inşa eden JS widget'ı vardır:


Başvuru için, burada gerçekten yapmaya çalışıyorum budur. Widgettaki değişikliklerin birçoğu, ağaçtaki bazı düğmelerin tıklanmasını içerir, ki bu ağaçtan ekler veya siler (muhtemelen kendini siler.) Ancak, düğümlerin bir kısmı daha karmaşık düzenleme işlemlerine ihtiyaç duyar, bu yüzden bir araç ipucu getirmek istiyorum kullanıcı fareyle üzerine geldiğinde talimatlar ve muhtemelen daha fazla düğme ile veya hatta kullanıcı bunları tıklarsa diyalogu saklayın. Ancak kullanıcı fikrini değiştirebilir ve düğümü veya düğümün herhangi bir ebeveyni silmeye karar verebilir, bu durumda diyalog gitmelidir. Şu anda, iletişim kutusunun el ile oluşturulduğu here olan bir uygulamanın görünümünü görüntüleyebilirsiniz. Güzel bir araç ipucu kütüphanesi kullanmaya başlamak istiyorum, ancak hepsinin yukarıda tarif ettiğim hatalar var.

+0

Karşılıklı bir açılışınız olmadığında '' etiketine sahip olmanızın bir sebebi var mı? Yayınınız da geçersiz html. Kapanış süresine ihtiyacın var. – Daedalus

+0

Üzgünüm, bir yazım hatası oldu. –

+0

Yaygınlığınız geçersiz html olmaya devam ediyor. mevcut değil. – Daedalus

cevap

0

deneyin: Modern tarayıcılarda

<script> 
    var liveToolTip = new Array(); 
    function addLiveToolTip(elName){ 
     if(elName in liveToolTip){ 
     }else{ 
      liveToolTip[elName]=1;} 
    } 
    function removeLiveToolTip(elName){ 
     if(elName in liveToolTip){ 
      delete liveToolTip[elName]; 
     } 
    } 
    function runOnMouseOuts() { 
     for(mouseOut in liveToolTip) { 
      document.getElementById(mouseOut).onmouseout(); 
     } 
    } 
</script> 
<div id="bar"> 
    <div onmouseover="addLiveToolTip(this.id);document.bgColor='gray'" 
     onmouseout="removeLiveToolTip(this.id);document.bgColor='white'" style="border:1px solid black;" id="foo"> 
     <span onclick="document.getElementById('bar').innerHTML = '';runOnMouseOuts()"> 
     Remove me</span> 
    </div> 

+0

Bu çözüm modülerlik testinde başarısız oluyor. Çubuğun içinde birden fazla onmouseout işleyici varsa ne olurdu? –

+0

Ben çağrılmış onmouseoutevent umut olduğunu düşündüm. Alternatif olarak arka plan rengini doğrudan değiştirebilirsiniz. Bunu yapmam için düzenledim. –

+0

Düzenlemeniz, ** belgesinin ** arka planının değiştirildiğini dikkate alarak önemli bir sorun teşkil etmemektedir; 'div' ** çubuğunun içeriği değil **. – Daedalus

2

, DOMNodeRemoved olay yoktur. Yani:

var div = document.getElementsByTagName('div')[0]; 
div.addEventListener('DOMNodeRemoved', function(e){ 
    document.bgColor='white'; 
});​ 

http://jsfiddle.net/HX88L/

kötü bir şey, o olay zaten deprecated olduğunu. mutation events'un yerine geçmek, henüz kullanıma hazır görünmüyor. MDN doküman sayfası hala sadece stub.

+0

Güzel! Tarayıcının ne kadar modern olması gerektiğini biliyor musun? Düzenleme: Re, değer kaybı, bu berbat! –

+0

Bunu okumak için IE9, Chrome ve Firefox üzerinde çalışıyorum - bkz. Http://stackoverflow.com/a/6987471/825789 – bfavaretto

+0

Her ne sebeple olursa olsun, tam olarak bu işe yaramayacak kadar gariptir. Neden olduğunu bilmiyorum. –