Bonjour,
J'aurais vraiment besoin de votre aide et vos connaissances en jquery s'il vous plait.
J'ai un site internet en une page ou j'aimerais que mes barres de progrès se lancent quand on scroll dessus. Pour l'instant j'ai le code pour lancer l'animation à la fin du chargement de la page .
Je vous joint le fiddle pour vous montrer: http://jsfiddle.net/as2gv/4/
Mon code pour animer mes barre des progres :
$(function () {
$(bar).each(function () {
bar_width = $(this).attr('aria-valuenow');
$(this).width(bar_width + '%');
});
});
if (window.scrollTop || document.documentElement.scrollTop || document.body.scrollTop > TaValeur) {
taDiv.style.width = "TaWidth";
}
Sinon tu as des scrollspy simples à utiliser en jquery
https://gist.github.com/loganbraga/81384ede6f69f55af152
Pour info, j'ai piqué le gros du code sur StackOverflow, mais impossible de remettre la main dessus. Si quelqu'un retrouve le lien, y'aura sans doutes plus d'explications.
En gros, on a une fonction isElementInViewport qui renvoie un booléen indiquant si l'élément passé en argument est visible dans la fenêtre du navigateur de l'utilisateur.
On a ensuite une fonction checkAnimation qui effectue une action si l'élément passé en argument est bien visible (fonction précédente), et n'a pas déjà été animé (présence de la classe animateClass, par exemple). Si c'est bon, on fait les opérations qu'on veut, donc dans ton cas ton animation js (et on ajoute la classe animateClass pour pas que l'animation se relance si l'utilisateur scrolle vers le bas puis remonte, par exemple).
Enfin, on attache un gestionnaire d'évènements sur le scroll de la souris qui appelle la fonction précédente et mets donc en place tout ce qu'on a vu.
Tu te retrouves donc avec des éléments animables une fois que t'es sûr que l'utilisateur les voit.
Après t'as pas mal de plugins pour faire ça directement, mais c'est tellement court que ça te suffira sans doute.
Merci à tous pour vos réponses, J'ai essayé d'utiliser ton code Caletlog mais ça ne veut toujours pas se lancer quand je scroll : http://jsfiddle.net/as2gv/4/
voici ce que j'ai mis :
// Check if elem is in viewport
function isElementInViewport(elem) {
var $elem = $(elem);
// Get the scroll position of the page.
var scrollElem = ((navigator.userAgent.toLowerCase().indexOf('webki
t')
!= -1) ? 'body' : 'html');
var viewportTop = $(scrollElem).scrollTop();
var viewportBottom = viewportTop + $(window).height();
// Get the position of the element on the page.
var elemTop = Math.round( $elem.offset().top );
var elemBottom = elemTop + $elem.height();
return ((elemTop < viewportBottom) && (elemBottom > viewportTop));
}
// Check if it's time to start the animation.
function checkAnimation(elem) {
var $elem = $(elem);
if ($elem.hasClass('.progress-bar')) return;
if (isElementInViewport($elem)) {
$elem.addClass('.progress-bar');
}
}
// Capture scroll events
$(window).scroll(function(){
checkAnimation( $('.progress-bar') );
});
Merci encore pour votre aide
Salut,
Comme ça, je vois déjà 2 erreurs : $().addClass sait qu'il ajoute une classe ; on ne lui donne pas un sélecteur de classe css en argument, juste le nom de la classe (donc tu peux enlever le .). Même remarque pour hasClass.
Ensuite, le problème c'est que tu fais sortir de la fonction si l'élément a la classe 'progress-bar', alors qu'on sait qu'il l'a (en tout cas, tu lui a mis dans ton jsfiddle). Cette clause return dans checkAnimation est là pour ne pas qu'une animation se répète plusieurs fois ; faut donc lui passer (ainsi qu'à l'addClass en dessous) le nom d'une classe qui n'est pas initialement présente sur l'objet, et qui est ajoutée une fois qu'il a été animé pour savoir, justement, qu'il l'a été et n'a pas besoin de l'être à nouveau.
Par ailleurs, si tu n'ajoute aucune classe d'animation ou n'anime pas manuellement l'objet, rien ne se passera.
Et cette classe d'animation, elle doit avoir des propriétés css ?
Ça dépend ; c'est un problème populaire, y'a des tas d'approches. Ce que je t'ai proposé, c'est :
- On a une fonction isElemInViewport qui renvoie true si l'élément passé est visible par l'utilisateur, faux sinon
- On a une fonction checkAnimation qui, lorsqu'elle est appelée, appelle la fonction précédente. Si elle renvoie faux, on ne fait rien.
---- Là, on vérifie si l'élément a une classe arbitraire, qui signifie que cet élément a déjà été animé. Par défaut donc, l'élément ne dispose pas de cette classe, et cette classe ne fait rien en elle-même (enfin, rien dans ce qui nous concerne pour l'instant, après t'en fais ce que tu veux de cette classe post-animation). Si cet élément a cette classe, c'est qu'il a déjà été animé, et donc on ne fait rien.
---- Si cet élément n'a pas cette classe, c'est qu'il n'a pas été animé. On peut donc l'animer. C'est donc ici que tu animes l'élément, soit tout en JS, soit en lui ajoutant, cette fois-ci, une classe qui est animée en CSS (qui accroche l'élément visé à des animations @keyframes, par exemple). En lui ajoutant cette classe animée, l'élément va s'animer à ce moment-là, et voilà. On oublie pas d'ajouter à la fin la classe arbitraire qui permet d'identifier que l'élément a été animé. (et comme tu t'en doute, il est possible de fusionner ces 2 classes (la classe marqueur présente si l'élément a été animé, et la classe qui anime l'objet) en une seule (si l'élément a déjà la classe qui anime, c'est qu'il a été animé), à condition que tu ne te serves pas de la classe marqueur (comme, par exemple, d'une classe 'post-animation').) C'était mon cas dans l'exemple que je t'ai donné donc on avait bien 2 classes différentes.
- On ajoute tout ça au gestionnaire d’événement scroll.
Ah merci ça marche , j'ai mis du temps a comprendre mais ca y'est j'ai compris. Merci encore en tout cas Caletlog tu assures.
Juste un dernière question. J'ai plusieurs barres de progrès avec des classes css différents (progress-bar-warning; progress-bar-danger...) : http://jsfiddle.net/as2gv/11/
Comment faire pour démarrer l'animation progress-bar-danger quand on scroll dessus sachant que l'animation progress-bar-warning est fini ?
Tu veux que l'animation danger démarre uniquement si elle est visible ET que l'animation warning du dessus a été réalisée, c'est ça ?
bah en fait que chaque catégorie(danger, warning) se déclencha que quand elle est visible oui. Je dois créer un nouveau Checkannimation ?
Tu peux mettre plusieurs checkAnimation dans le handler du scroll, avec chacun un argument différent, par exemple.
Si tu t'occupe d'éléments qui ont la même classe, ils vont, par défaut, tous s'activer en même temps dès qu'au moins un est visible (même si les autres ne le sont pas) étant donné que les objets jQuery manipulés peuvent être des collections d'objets du DOM.
Pour empêcher ça, tu peux utiliser des itérateurs, soit pour lancer checkAnimation sur chaque objet de même classe (et donc les individualiser dans leur animation), soit, une fois dans checkAnimation, pour itérer sur les objets visibles uniquement.
Attention quand même aux performances. J'ai pas le moyen de tester là, mais si j'étais toi je ferais quelques tests avec chacune des méthodes que tu utilise avec éventuellement un rajout de 'breakpoints' pour sortir des boucles inutiles là ou c'est nécessaire. Quand on commence à faire des itérations sur d'éventuelles grosses collections dans des évènements aussi fréquents que le scroll souris, ça peut vite dégénérer
Je réfléchirai à une méthode sans doute plus optimisée quand j'aurai un peu plus de temps.
Je pense que je suis entrain d'aller dans la mauvaise direction : http://jsfiddle.net/as2gv/12/