2010-09-27 17 views
19

Existe-t-il une technique ou un ensemble de techniques pouvant être utilisé pour implémenter ce qui, en fait, serait un 'événement' onVisible dans JavaScript? Je souhaite que mon JavaScript détecte lorsqu'un élément d'une page Web, tel qu'un paragraphe de texte ou une image, devient visible dans la fenêtre d'un navigateur lorsque l'utilisateur fait défiler une page vers le bas. Je voudrais également qu'un "event" correspondant, onNotVisible, se déclenche lorsqu'un élément qui était visible dans la fenêtre du navigateur ne peut plus être vu.Comment implémenter un événement 'onVisible' en Javascript?

S'il ne peut pas être implémenté facilement en JavaScript, y a-t-il des événements spécifiques au navigateur qui peuvent fournir la même fonctionnalité?

+0

peut être cela pourrait vous aider http://stackoverflow.com/questions/399867/custom-events-in-jquery –

+2

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

Répondre

5

Vous devez configurer un écouteur d'événement pour l'événement de décollage du document ou de la fenêtre. Ensuite, vous mesurer la zone actuellement visible en ajoutant le clientHeight à scrollTop, puis vous vérifiez si votre élément de choix est dans cette zone. Quelque chose comme ça

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 c'est le cas, vous placez un drapeau quelque part dans votre code.

Vous risquez cependant de rencontrer des incompatibilités de navigateur. Donc, mieux utiliser une bibliothèque.

+0

Comment vérifier si un élément de choix se trouve dans cette zone? – RobertG

+0

J'ai ajouté un exemple. – DanMan

8

je devais essayer moi-même, et ce que je suis venu avec:

<!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> 

testé dans:

  • FireFox 3.6 (travaux)
  • Chrome 6.0.472 (œuvres
  • Opera 10.62 (fonctionne)
  • Safari 4 (Fonctionne dans un très buggy et manière irritante, ne nous e popups si vous essayez ici!)

(The code is also available on PasteBin)

Le code ci-dessus n'est pas optimisé en aucune façon, je viens de commencer à écrire et a pris fin lorsque cela a fonctionné. De préférence, vous voudrez probablement utiliser une seule file d'attente, refactoriser du code et le rendre plus générique. Fourni tel quel.

+0

+1 bonne réponse complète. – LarsH

+1

bonne réponse. Cela ne tient pas compte de l'attribut d'affichage! Il faudra traverser le parentNode de l'élément et vérifier si tous ses attributs d'affichage sont visibles. Très utile pour le chargement de contenu à la demande. –

+0

Ici, c'est sur jsbin: http://jsbin.com/ewoqey/1/edit –

4

L'un des answers dans le question lié ci-dessus par @edbond donne un pointeur sur le jQuery appear plugin. Ce plugin vous permet d'attacher des rappels appear et disappear à un élément appelé lorsque l'élément défile et disparaît, ce qui correspond exactement à ce que vous recherchez.

Questions connexes