Activation d'une popover au défilement

This commit is contained in:
Paul TREHIOU 2016-08-24 14:21:01 +02:00
parent b6d630bcd5
commit 41b98d7b34
3 changed files with 263 additions and 1 deletions

View File

@ -122,7 +122,7 @@
<img src="img/trombone.gif" alt="icone trombone">
<h3>Les instruments enseignés sont</h4>
<ul class="list-group">
<li class="list-group-item" data-toggle="popover" data-content="Nathalie ROHRBACH" data-title="Enseignant">Le chant
<li class="list-group-item track" data-toggle="popover" data-content="Nathalie ROHRBACH" data-title="Enseignant">Le chant
<li class="list-group-item" data-toggle="popover" data-content="Robert SCHMIDT" data-title="Enseignant">La flûte traversière et la flûte à bec
<li class="list-group-item" data-toggle="popover" data-content="Régis MAERKY" data-title="Enseignant">La clarinette
<li class="list-group-item" data-toggle="popover" data-content="Régis MAERKY" data-title="Enseignant">Les saxophones
@ -172,11 +172,23 @@
<!-- Bootstrap Core JavaScript -->
<script src="vendor/bootstrap/js/bootstrap.min.js"></script>
<script src="vendor/appear/appear.min.js"></script>
<script type="text/javascript">
$(function () {
$('[data-toggle="popover"]').popover({trigger: "hover"})
})
appear({
elements: function elements(){
// work with all elements with the class "track"
return document.getElementsByClassName('track');
},
appear: function appear(el){
console.log('visible', el);
$(el).popover('show');
},
});
</script>
<!-- Plugin JavaScript -->

248
vendor/appear/appear.js vendored Normal file
View File

@ -0,0 +1,248 @@
/* appear.js 1.0.3 */
appear = (function(){
'use strict';
var scrollLastPos = null, scrollTimer = 0, scroll = {};
function track(){
var newPos = window.scrollY || window.pageYOffset; // pageYOffset for IE9
if ( scrollLastPos != null ){
scroll.velocity = newPos - scrollLastPos;
scroll.delta = (scroll.velocity >= 0) ? scroll.velocity : (-1 * scroll.velocity);
}
scrollLastPos = newPos;
if(scrollTimer){
clearTimeout(scrollTimer);
}
scrollTimer = setTimeout(function(){
scrollLastPos = null;
}, 30);
}
addEventListener('scroll', track, false);
// determine if a given element (plus an additional "bounds" area around it) is in the viewport
function viewable(el, bounds){
var rect = el.getBoundingClientRect();
return (
(rect.top + rect.height) >= 0 &&
(rect.left + rect.width) >= 0 &&
(rect.bottom - rect.height) <= ( (window.innerHeight || document.documentElement.clientHeight) + bounds) &&
(rect.right - rect.width) <= ( (window.innerWidth || document.documentElement.clientWidth) + bounds)
);
}
return function(obj){
return (function(obj){
var initd = false, elements = [], elementsLength, reappear = [],
appeared = 0, disappeared = 0, timer, deltaSet, opts = {}, done;
// handle debouncing a function for better performance on scroll
function debounce(fn, delay) {
return function () {
var self = this, args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
fn.apply(self, args);
}, delay);
};
}
// called on scroll and resize event, so debounce the actual function that does
// the heavy work of determining if an item is viewable and then "appearing" it
function checkAppear() {
if(scroll.delta < opts.delta.speed) {
if(!deltaSet) {
deltaSet = true;
doCheckAppear();
setTimeout(function(){
deltaSet = false;
}, opts.delta.timeout);
}
}
(debounce(function() {
doCheckAppear();
}, opts.debounce)());
}
function begin() {
// initial appear check before any scroll or resize event
doCheckAppear();
// add relevant listeners
addEventListener('scroll', checkAppear, false);
addEventListener('resize', checkAppear, false);
}
function end() {
elements = [];
if(timer) {
clearTimeout(timer);
}
removeListeners();
}
function removeListeners() {
removeEventListener('scroll', checkAppear, false);
removeEventListener('resize', checkAppear, false);
}
function doCheckAppear() {
if(done) {
return;
}
elements.forEach(function(n, i){
if(n && viewable(n, opts.bounds)) {
// only act if the element is eligible to reappear
if(reappear[i]) {
// mark this element as not eligible to appear
reappear[i] = false;
// increment the count of appeared items
appeared++;
// call the appear fn
if(opts.appear) {
opts.appear(n);
}
// if not tracking reappears or disappears, need to remove node here
if(!opts.disappear && !opts.reappear) {
// stop tracking this node, which is now viewable
elements[i] = null;
}
}
} else {
if(reappear[i] === false) {
if(opts.disappear) {
opts.disappear(n);
}
// increment the dissappeared count
disappeared++;
// if not tracking reappears, need to remove node here
if(!opts.reappear) {
// stop tracking this node, which is now viewable
elements[i] = null;
}
}
// element is out of view and eligible to be appeared again
reappear[i] = true;
}
});
// remove listeners if all items have (re)appeared
if(!opts.reappear && (!opts.appear || opts.appear && appeared === elementsLength) && (!opts.disappear || opts.disappear && disappeared === elementsLength)) {
// ensure done is only called once (could be called from a trailing debounce/throttle)
done = true;
removeListeners();
// all items have appeared, so call the done fn
if(opts.done){
opts.done();
}
}
}
function init() {
// make sure we only init once
if(initd) {
return;
}
initd = true;
// call the obj init fn
if(opts.init) {
opts.init();
}
// get the elements to work with
var els;
if(typeof opts.elements === 'function') {
els = opts.elements();
} else {
els = opts.elements;
}
if(els) {
// put elements into an array object to work with
elementsLength = els.length;
for(var i = 0; i < elementsLength; i += 1) {
elements.push(els[i]);
reappear.push(true);
}
begin();
}
}
return function(obj) {
obj = obj || {};
// assign the fn to execute when a node is visible
opts = {
// a function to be run when the dom is ready (allows for any setup work)
init: obj.init,
// either an array of elements or a function that will return an htmlCollection
elements: obj.elements,
// function to call when an element is "viewable", will be passed the element to work with
appear: obj.appear,
// function to call when an element is no longer "viewable", will be passed the element to work with
disappear: obj.disappear,
// function to call when all the elements have "appeared"
done: obj.done,
// keep tracking the elements
reappear: obj.reappear,
// the extra border around an element to make it viewable outside of the true viewport
bounds: obj.bounds || 0,
// the debounce timeout
debounce: obj.debounce || 50,
// appear.js will also check for items on continuous slow scrolling
// you can controll how slow the scrolling should be (deltaSpeed)
// and when it will check again (deltaTimeout) after it has inspected the dom/viewport;
delta: {
speed: obj.deltaSpeed || 50,
timeout: obj.deltaTimeout || 500
}
};
// add an event listener to init when dom is ready
addEventListener('DOMContentLoaded', init, false);
var isIE10 = false;
if (Function('/*@cc_on return document.documentMode===10@*/')()){
isIE10 = true;
}
var completeOrLoaded = document.readyState === 'complete' || document.readyState === 'loaded';
// call init if document is ready to be worked with and we missed the event
if (isIE10) {
if (completeOrLoaded) {
init();
}
} else {
if (completeOrLoaded || document.readyState === 'interactive') {
init();
}
}
return {
// manually fire check for visibility of tracked elements
trigger: function trigger(){
doCheckAppear();
},
// pause tracking of elements
pause: function pause(){
removeListeners();
},
// resume tracking of elements after a pause
resume: function resume(){
begin();
},
// provide a means to stop monitoring all elements
destroy: function destroy() {
end();
}
};
};
}()(obj));
};
}());

2
vendor/appear/appear.min.js vendored Normal file
View File

@ -0,0 +1,2 @@
/* appear.min.js 1.0.3 */
appear=function(){"use strict";function e(){var e=window.scrollY||window.pageYOffset;null!=n&&(o.velocity=e-n,o.delta=o.velocity>=0?o.velocity:-1*o.velocity),n=e,i&&clearTimeout(i),i=setTimeout(function(){n=null},30)}function t(e,t){var n=e.getBoundingClientRect();return n.top+n.height>=0&&n.left+n.width>=0&&n.bottom-n.height<=(window.innerHeight||document.documentElement.clientHeight)+t&&n.right-n.width<=(window.innerWidth||document.documentElement.clientWidth)+t}var n=null,i=0,o={};return addEventListener("scroll",e,!1),function(e){return function(e){function n(e,t){return function(){var n=this,i=arguments;clearTimeout(l),l=setTimeout(function(){e.apply(n,i)},t)}}function i(){o.delta<y.delta.speed&&(s||(s=!0,d(),setTimeout(function(){s=!1},y.delta.timeout))),n(function(){d()},y.debounce)()}function r(){d(),addEventListener("scroll",i,!1),addEventListener("resize",i,!1)}function a(){v=[],l&&clearTimeout(l),u()}function u(){removeEventListener("scroll",i,!1),removeEventListener("resize",i,!1)}function d(){f||(v.forEach(function(e,n){e&&t(e,y.bounds)?h[n]&&(h[n]=!1,g++,y.appear&&y.appear(e),y.disappear||y.reappear||(v[n]=null)):(h[n]===!1&&(y.disappear&&y.disappear(e),w++,y.reappear||(v[n]=null)),h[n]=!0)}),y.reappear||y.appear&&(!y.appear||g!==p)||y.disappear&&(!y.disappear||w!==p)||(f=!0,u(),y.done&&y.done()))}function c(){if(!m){m=!0,y.init&&y.init();var e;if(e="function"==typeof y.elements?y.elements():y.elements){p=e.length;for(var t=0;p>t;t+=1)v.push(e[t]),h.push(!0);r()}}}var p,l,s,f,m=!1,v=[],h=[],g=0,w=0,y={};return function(e){e=e||{},y={init:e.init,elements:e.elements,appear:e.appear,disappear:e.disappear,done:e.done,reappear:e.reappear,bounds:e.bounds||0,debounce:e.debounce||50,delta:{speed:e.deltaSpeed||50,timeout:e.deltaTimeout||500}},addEventListener("DOMContentLoaded",c,!1);var t=!1;Function("/*@cc_on return document.documentMode===10@*/")()&&(t=!0);var n="complete"===document.readyState||"loaded"===document.readyState;return t?n&&c():(n||"interactive"===document.readyState)&&c(),{trigger:function(){d()},pause:function(){u()},resume:function(){r()},destroy:function(){a()}}}}()(e)}}();