Salut !

je suis en train d'intégrer une animation a mon futur site et j'ai un truc qui coince...

Le but de mon animation :

  • créer un fonction qui va créer 16 div avec des Id différents ( #div1, #div2...) et appliquer du css via JS pour former des carrés de différentes couleurs
  • appliquer une animation sur cette fonction via le rajout d'une class déja présente sur la feuille de css , ET c'est la ou je galère.

Voila mon bout de code qui bug :

HTML :

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Document sans nom</title>
    <link rel="stylesheet" href="css.css">
</head>
<body>
    <div id="div">  </div>
    <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
    <script language="javascript" src="js.js"></script>
</body>
</html>

CSS :

/* CSS Document */

.animation{
    animation: fadein 2s ease-in-out;
    animation-iteration-count: infinite;
}

@keyframes fadein {
    from { opacity: 0; }
    to   { opacity: 1; }
}

JS :

function generate (){

    for(var i = 1; i < 16; i++) {
        var elt = document.createElement("div");
        elt.id = "div" +i;
        elt.style.width = "50px";
        elt.style.height = "50px";
        elt.style.borderRadius = "10px";
        elt.style.backgroundColor = '#'+Math.random().toString(16).substr(2,6);
        elt.style.position = "absolute";
        elt.style.top = Math.random()*1000 + "px";
        elt.style.left = Math.random()*1000 + "px";
        document.getElementById("div" + i).classList.add('animation');
        document.getElementById("div").appendChild(elt);

    } 

}
setInterval(generate, 4000);

si j'enlève la ligne de JS concernant l'ajout de la class, mon code marche très bien mais du coup j'ai pas mon animation et ça c'est embêtant !

Dans la console ça me donne : " Cannot read property 'classList' of null" j'ai beau chercher je ne trouve pas la solution..

Merci pour votre aide!

10 réponses


Maenhyr
Réponse acceptée

Bonjour,

c'est normal d'avoir cette erreur, Tu ajoutes la div généré par JS grâce à document.getElementById("div").appendChild(elt);.

Hors lorsque tu veux ajouter le classList, tu utilises document.getElementById("div" + i) mais cette div n'existe pas encore dans le DOM (ni dans document donc).

tu peux essayer elt.classList.add('animation') ou inverser les deux dernières lignes de ta boucle.

Lartak
Réponse acceptée

Aurais tu une solution pour faire reboot mon animation tout en gardant la création des div via JS et non par HTML ?

Si je comprend bien, à chaque fois que la fonction generate est appelée, tu veux refaire tes animations, soit la création des éléments dans la div avec l'ID div, il te suffit donc de supprimer le contenu de cet élément à chaque appel de la fonction avant même de créer les autres éléments.
Je t'ai fait un petit exemple ici.
De cette manière, seule la div avec l'ID div est créée sur la page en HTML, les autres éléments sont créés via JS.

Merci pour ton astuce ça marche super ! en revanche ça me pose un autre problème..

Le but de mon "setInterval(generate, 4000)" est de réinitialiser l'animation toute les 4 sec. depuis que j'ai intégré ton astuce l'animation N s'affiche, 4 secondes après l'animation N1 s'affiche mais l'animation N ne disparait plus... et du coup ça devient beaucoup trop encombrant..

Une dernière astuce ? =)

si je comprends bien, tu veux supprimer les divs de l'animation précédentes, c'est ça?

Oui c'est ça ! (dsl du délais de réponse !)

J'aimerai que l'animation N s'efface l'orsque l'animation N1 apparait.

J'ai bidouillé mais j'ai pas trouvé. Sur la toute première version de mon animation j'ai moi même intégré les div en html et le reboot s'effectuait sans problème, mais avec la création des div ça veut plus reboot...

Bonjour.
Il y a un sacré problème dans ton code, car tu définies à plusieurs reprises les mêmes valeurs pour l'attribut id d'élément.
En effet, dans ta boucle qui est répétée à plusieurs reprises via ton setInterval, lors de la première boucle pas de problème, mais dès la seconde, tu vas te retrouver avec plusieurs éléments ayant par exemple l'ID div2, alors qu'un ID doit être unique sur une même page.
Ensuite, tu devrais remplacer document.getElementById("div" + i) par document.getElementById(elt.id), car de cette mnière si à un moment donné tu veux changer la valeur id de l'élément, ça t'évitera de devoir faire des modifications sur cette ligne de code pour la sélection de l'élément.

Bonjour, Lartak et merci pour ton commentaire,

J'ai effectivement modifié mon document.getElement... en revanche je cherche a faire reboot mon animation et dans ce sens il n'y aurait plus de répétition de div.

mais je sais pas comment faire, a part créer les div directement dans le HTML mais mon but est de les créer via JS pour éviter d'alourdir mon HTML.

Voici ma première version :

HTML :

<body>

    <div id="div">

        <div id="div1"></div>
        <div id="div2"></div>
        <div id="div3"></div>
        <div id="div4"></div>
        <div id="div5"></div>
        <div id="div6"></div>
        <div id="div7"></div>
        <div id="div8"></div>
        <div id="div9"></div>
        <div id="div10"></div>
        <div id="div11"></div>
        <div id="div12"></div>
        <div id="div13"></div>
        <div id="div14"></div>
        <div id="div15"></div> 

    </div>

    <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
    <script language="javascript" src="js.js"></script>
</body>

JS :

function generate (){

    for(var i = 1; i < 16; i++) {

            var elt = document.getElementById("div" + i);
            elt.style.width = "50px";
            elt.style.height = "50px";
            elt.style.borderRadius = "10px";
            elt.style.backgroundColor = '#'+Math.random().toString(16).substr(2,6);
            elt.style.position = "absolute";
            elt.style.top = Math.random()*1000 + "px";
            elt.style.left = Math.random()*1000 + "px";
            document.getElementById("div" + i).classList.add('animation');
        }
}

setInterval(generate, 4000);

Sur ce modèle mon reboot d'animation marche, mais mon HTML est chargé des 16 divs....

Aurais tu une solution pour faire reboot mon animation tout en gardant la création des div via JS et non par HTML ?

Merci

Super ! Merci beaucoup pour le coup de pouce !

Histoire que je comprenne bien le fonctionnement, pourrais tu m'expliquer l'utilité de " div.innerHTML = ' '; " stp ?

Sinon je comprend déja que tu créés une section sur la div deja en place dans le html et que tu inclus la nouvelle div a la section créée puis tu inclus la section dans la div existante. (c'est bien ça ?)

Vu que je suis quand meme débutant j'aime comprendre pour pouvoir le réutiliser ^^

le div.innerHTML = '', s'est pour vider le contenu de <div id="div"></div>, donc tout ce qui à pu être créé et placé dedans via JS.

Ok merci pour tes explications !!