2010-09-27 16 views
19

¿Existe alguna técnica o conjunto de técnicas que se puedan utilizar para implementar lo que, en efecto, sería un 'evento' visible en JavaScript?¿Cómo implementar un evento 'onVisible' en Javascript?

Me gustaría que mi JavaScript detecte cuando un elemento en una página web, como un párrafo de texto o una imagen, se vuelve visible en una ventana del navegador cuando un usuario se desplaza hacia abajo en una página. También me gustaría que se active un 'evento' correspondiente, en NoVisible, cuando ya no se puede ver un elemento que una vez fue visible en la ventana del navegador.

Si no se puede implementar fácilmente en JavaScript, ¿hay algún evento específico del navegador que pueda proporcionar la misma funcionalidad?

+0

puede ser esto podría ayudarlo http://stackoverflow.com/questions/399867/custom-events-in-jquery –

+2

ver http://stackoverflow.com/questions/487073/jquery-check-if-element- is-visible-after-scroling – edbond

Respuesta

5

Tendría que configurar un detector de eventos para el evento onscroll del documento o la ventana. Luego mida el área actualmente visible añadiendo el cliente Height para scrollTop, y luego verifique si su elemento de elección está dentro de esa área. Algo como esto

myElem=document.getElementById('some_id'); 
scrollOffset=document.getElementsByTagName('html')[0].scrollTop; 
visibleHeight=document.getElementsByTagName('html')[0].clientHeight; 
if(myElem.offsetTop>=scrollOffset && myElem.offsetTop<=scrollOffset+visibleHeight){ 
    // element is in visible area 
} 

Si ese es el caso, establezca alguna bandera en algún lugar de su código.

Sin embargo, es probable que encuentre incompatibilidades en el navegador. Así que es mejor usar alguna biblioteca.

+0

¿Cómo verifico si un elemento de elección está dentro de esta área? – RobertG

+0

He agregado un ejemplo. – DanMan

8

que tenía que probar esto por mí mismo, y esto es lo que ocurrió:

<!DOCTYPE html> 
<html> 
<head> 
<script> 

var EventListener = function(element, callback) { 
    this._el = element; 
    this._cb = callback; 
    this._at = false; 
    this._hasBeenVisible = false; 
    this._hasBeenInvisible = true; 
    var _me = this; 

    window.onscroll = function() { 
     for (q in EventListener.queue.onvisible) { 
      EventListener.queue.onvisible[q].call(); 
     } 
     for (q in EventListener.queue.oninvisible) { 
      EventListener.queue.oninvisible[q].call(); 
     } 
    }; 

    return { 
     onvisible: function() { 
      EventListener.queue.onvisible.push(function() { 
       if (!_me._at && _me._hasBeenInvisible && (window.pageYOffset + window.innerHeight) > _me._el.offsetTop && window.pageYOffset < (_me._el.offsetTop + _me._el.scrollHeight)) { 
        _me._cb.call(); 
        _me._at = true; 
        _me._hasBeenVisible = true; 
       } 
      }); 
      EventListener.queue.oninvisible.push(function() { 
       if (_me._hasBeenVisible && ((window.pageYOffset + window.innerHeight) < _me._el.offsetTop || window.pageYOffset > (_me._el.offsetTop + _me._el.scrollHeight))) { 
        _me._hasBeenInvisible = true; 
        _me._hasBeenVisible = false; 
        _me._at = false; 
       } 
      }); 
     }, 
     oninvisible: function() { 
      EventListener.queue.oninvisible.push(function() { 
       if (!_me._at && _me._hasBeenVisible && ((window.pageYOffset + window.innerHeight) < _me._el.offsetTop || window.pageYOffset > (_me._el.offsetTop + _me._el.scrollHeight))) { 
        _me._cb.call(); 
        _me._at = true; 
        _me._hasBeenInvisible = true; 
       } 
      }); 
      EventListener.queue.onvisible.push(function() { 
       if (_me._hasBeenInvisible && (window.pageYOffset + window.innerHeight) > _me._el.offsetTop && window.pageYOffset < (_me._el.offsetTop + _me._el.scrollHeight)) { 
        _me._hasBeenVisible = true; 
        _me._hasBeenInvisible = false; 
        _me._at = false; 
       } 
      }); 
     } 
    }; 
} 
EventListener.queue = { 
    onvisible: [], 
    oninvisible: [] 
}; 

function addListener(element, event, fn) { 
    if (typeof element == 'string') 
     element = document.getElementById(element); 

    var listener = new EventListener(element, fn); 

    if (listener['on' + event.toLowerCase()]) 
     return listener['on' + event.toLowerCase()].call(); 
} 

window.onload = function() { 
    addListener('event-element', 'visible', function() { 
     alert("Element One Visible!"); 
    }); 
    addListener('event-element', 'invisible', function() { 
     alert("Element One Invisible!"); 
    }); 
    addListener('event2-element', 'visible', function() { 
     alert("Element Two Visible!"); 
    }); 
    addListener('event2-element', 'invisible', function() { 
     alert("Element Two Invisible"); 
    }); 
} 

</script> 
</head> 
<body> 

<h1>Hey!</h1> 

<div style="height: 1500px;"> 
Please scroll down some pixels. 
</div> 

<p id="event-element"> 
    This element should cast an event 'onvisible' and 'oninvisible'. 
</p> 

<div style="height: 1000px;"> 

</div> 

<p id="event2-element"> 
    Another one! 
</p> 


</body> 
</html> 

Probado en:

  • Firefox 3.6 (obras)
  • Chrome 6.0.472 (obras)
  • Opera 10.62 (trabaja)
  • Safari 4 (Funciona de una manera irritante y irritante, no nos e popups si intenta aquí!)

(The code is also available on PasteBin)

El código anterior no se optimiza en forma alguna, acabo de empezar a escribir y terminaron en el que funcionaba. Preferiblemente, probablemente desee utilizar solo una cola, refactorizar algún código y hacerlo más genérico. Provisto como es

+0

+1 buena respuesta completa. – LarsH

+1

buena respuesta. Sin embargo, esto no cuenta para el atributo de visualización. Uno deberá atravesar parentNode hacia arriba del elemento y verificar si todos sus atributos de visualización están visibles. Muy útil para la carga de contenido bajo demanda. –

+0

Aquí está en jsbin: http://jsbin.com/ewoqey/1/edit –

4

Uno de los answers en el question vinculado anteriormente por @edbond da un puntero al jQuery appear plugin. Este complemento le permite adjuntar callbacks appear y disappear a un elemento que se invoca a medida que el elemento se desplaza hacia y fuera de la vista, que suena exactamente como lo que está buscando.

Cuestiones relacionadas