Problemas com mouseout evento
-
09-06-2019 - |
Pergunta
Eu estou usando o JavaScript para ocultar uma imagem e mostrar algum texto é escondido sob ele.Mas, quando o texto é mostrado se você rolar sobre ele, ele é acionado o mouseout evento no recipiente, que, em seguida, esconde o texto e mostra a imagem novamente, e ele só vai para um estranho laço.
O html tem esta aparência:
<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>
E o javascript (Ele usa um lightbox):
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;
}
Isto parece muito simples, mas eu simplesmente não posso envolver minha cabeça em torno dela.
Solução
Eu daria o contêiner div:
position: relative;
e adicionar uma terceira div no recipiente (deve ser o último filho do recipiente) com:
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
e pegar os eventos mouseover e mouseout neste div em vez disso.
Porque ele não tem nenhum elemento filho, você não deve se espúrias eventos mouseover e mouseout propagando-se para ele.
Editar:
O que eu acredito que acontece, é que quando o cursor move-se a partir de um elemento pai para uma criança elemento, um mouseout evento ocorre no elemento pai, e um evento mouseover ocorre no elemento filho.No entanto, se o mouseover do manipulador sobre o elemento filho não capturar o evento e de parar a propagação, o elemento pai também vai receber o evento mouseover.
Outras dicas
Parece que o que você realmente quer é mouseenter
/mouseleave
(Ou seja, proprietários de eventos, mas fácil de emular):
// 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);
Em alternativa, patch prototype.js e usar mouseenter
e mouseleave
com confiança.Observe que eu já expandiu a seleção para deixar a janela ou entrar em XUL chrome;isso parecia para corrigir alguns casos extremos no Firefox para mim.
Esta pode não ser a melhor solução, mas você pode definir um global variável booleana que seria acessível para ambos os métodos, que seria apenas especificar se a última ação foi HoverIn ou HoverOut.Você pode usar essa variável booleana para determinar se o código deve ser executado ou não.
if (bWasHoverIn){
...
}
Não deveria o evento onmouseover ser na imagem div e o evento onmouseout ser sobre o texto div?
@Ryan boolean não é realmente de ajuda, ele apenas evita que o loop, mas o evento mouseover ainda é acionado e o texto fica hiden.
@Brian costumava ser assim, mas ele se comportou da mesma maneira.
Eu não tenho certeza se encaixaria com o resto do seu estilo, mas, talvez, se você tiver alterado o css no texto div então foi o mesmo tamanho que a imagem, fixa ou o tamanho da div externas, em seguida, quando o evento mouseover acionado, o tamanho da div externas não mudaria muito a fazer com que o mouseout evento.
Isto faz sentido?