2017-01-30 1 views
0

J'essaye de faire un fondu en effet à un élément innerHTML changé en élément en utilisant JS de base et CSS.Fade-In Transition sur le changement de classe (JS) ne fonctionne pas

C'est la JS:

function PrintNote(taskIndex) { 
    //print a note, index is given to let the function know which task to print from the array 
    notesArea.innerHTML += "<div id='taskN" + taskIndex + "'><span trash='" + taskIndex + "' class='glyphicon glyphicon-remove-circle deleteBtn'></span><strong><span class='noteTitle'>Task #" + (taskIndex + 1) + "</span><p class='noteTXT'>" + tasksArray[taskIndex].text + "</p><span class='noteDate'>" + tasksArray[taskIndex].date + "</span></strong></div>" 
    //when done printing, get all the delete buttons into the deletesArray, give each the remove task function 
    noteDivsElement = document.querySelector("#taskN" + taskIndex); 
    noteDivsElement.className = 'fadeIn'; 
    deletesArray = document.getElementsByClassName("glyphicon glyphicon-remove-circle deleteBtn"); 
    for (var i = 0; i < deletesArray.length; i++) { 
     deletesArray[i].onclick = RemoveTask; 
    } 
} 

C'est le CSS:

div[id^="taskN"] { 
    background-image: url("images/notebg.png"); 
    background-repeat: no-repeat; 
    height: 250px; 
    width: 200px; 
    position: relative; 
    display: inline-block; 
    opacity: 0; 
    transition: opacity 1s ease-in; 
} 

div[id^="taskN"].fadeIn{ 
    opacity: 1; 
} 

post-scriptum Je dois utiliser JS de base (pas de JQuery et autres), car c'est pour un projet que je fais pour le cours FullStack, et nous sommes censés utiliser seulement les bases que nous avons apprises.

Une idée pourquoi ça ne marchera pas? Merci d'avance. :)

Répondre

0

Le navigateur est probablement le lot de toutes les instructions DOM dans 1 peinture. Par conséquent, tous les divs ont immédiatement un 'fadeIn' appliqué.

Pour que 'fadeIn' ne soit appliqué qu'au cycle de peinture suivant, utilisez reqeuestAnimationFrame.

Cela se traduira par le navigateur de voir un avant-état (opacité: 0) et après l'état (opacité: 1). Et par conséquent la transition donnera le coup dans

Quelque chose comme:

function PrintNote(taskIndex) { 
    //print a note, index is given to let the function know which task to print from the array 
    notesArea.innerHTML += "<div id='taskN" + taskIndex + "'><span trash='" + taskIndex + "' class='glyphicon glyphicon-remove-circle deleteBtn'></span><strong><span class='noteTitle'>Task #" + (taskIndex + 1) + "</span><p class='noteTXT'>" + tasksArray[taskIndex].text + "</p><span class='noteDate'>" + tasksArray[taskIndex].date + "</span></strong></div>" 

    //when done printing, get all the delete buttons into the deletesArray, give each the remove task function 
    var noteDivsElement = document.querySelector("#taskN" + taskIndex); 

    window.requestAnimationFrame(function(){ 
    noteDivsElement.className = 'fadeIn'; 
    }); 

    var deletesArray = document.getElementsByClassName("glyphicon glyphicon-remove-circle deleteBtn"); 
    for (var i = 0; i < deletesArray.length; i++) { 
    deletesArray[i].onclick = RemoveTask; 
    } 
} 

EDIT

Comme par commentaire, devrait être appelé ci-dessus dans une boucle. Doivent donc se assurer d'avoir une bonne fermeture sur noteDivsElement (1)

Pour expliquer un peu plus en détail: si vous deviez faire un console.log(noteDivsElement) après que le corps de la fonction de la noteDivsElement variable serait encore être réglée. C'est probablement contre-intuitif, mais c'est juste comment les vars fonctionnent en javascript. I.e .: il fuit à la portée globale. À chaque itération, cette variable est remplacée par la même variable. Étant donné que le paramètre fadeIn est retardé, toutes les affectations de fadeIn se produisent après la boucle et se produisent donc toutes sur la dernière affectation de noteDivsElement.

Ceci est un problème qui se produit beaucoup en javascript. Souvent, lorsqu'une opération en boucle et asynchrone est combinée. La méthode par défaut est de créer une fermeture qui lie la variable à un argument de fonction, la rendant disponible dans le contexte même après la fin de la boucle. C'est difficile à expliquer, veuillez lire le lien fourni en bas.

function PrintNote(taskIndex) { 
    //print a note, index is given to let the function know which task to print from the array 
    notesArea.innerHTML += "<div id='taskN" + taskIndex + "'><span trash='" + taskIndex + "' class='glyphicon glyphicon-remove-circle deleteBtn'></span><strong><span class='noteTitle'>Task #" + (taskIndex + 1) + "</span><p class='noteTXT'>" + tasksArray[taskIndex].text + "</p><span class='noteDate'>" + tasksArray[taskIndex].date + "</span></strong></div>" 

    //when done printing, get all the delete buttons into the deletesArray, give each the remove task function 
    var noteDivsElement = document.querySelector("#taskN" + taskIndex); 

    (function(el){ 
    //'el' is part of closure and is a local variable only to this iteration 
    window.requestAnimationFrame(function(){ 
     el.className = 'fadeIn'; 
    }); 
    }(noteDivsElement)) 


    var deletesArray = document.getElementsByClassName("glyphicon glyphicon-remove-circle deleteBtn"); 
    for (var i = 0; i < deletesArray.length; i++) { 
    deletesArray[i].onclick = RemoveTask; 
    } 
} 

Une autre ES6-chemin à accomplir la même chose avec une variable locale appropriée à l'aide let au lieu de var qui contourne tous les problèmes ont parlé. Ceci est pas pris en charge dans tous les navigateurs encore bien:

function PrintNote(taskIndex) { 
    //print a note, index is given to let the function know which task to print from the array 
    notesArea.innerHTML += "<div id='taskN" + taskIndex + "'><span trash='" + taskIndex + "' class='glyphicon glyphicon-remove-circle deleteBtn'></span><strong><span class='noteTitle'>Task #" + (taskIndex + 1) + "</span><p class='noteTXT'>" + tasksArray[taskIndex].text + "</p><span class='noteDate'>" + tasksArray[taskIndex].date + "</span></strong></div>" 

    //when done printing, get all the delete buttons into the deletesArray, give each the remove task function 
    //NOTE THE 'let' here 
    let noteDivsElement = document.querySelector("#taskN" + taskIndex); 

    window.requestAnimationFrame(function(){ 
    noteDivsElement.className = 'fadeIn'; 
    }); 

    var deletesArray = document.getElementsByClassName("glyphicon glyphicon-remove-circle deleteBtn"); 
    for (var i = 0; i < deletesArray.length; i++) { 
    deletesArray[i].onclick = RemoveTask; 
    } 
} 

BTW: avoir à utiliser des fermetures et window.requestAnimationFrame ne me frappe pas dans le cadre d'un cours débutants JS afin que je puisse vous ai poussé dans la mauvaise direction . Sans tenir compte des fermetures est une partie très importante de savoir javascript alors j'espère que cela aide encore. Bonne chance!

1) how do closures work

+0

Hey, merci pour répondre :) Je vais essayer ce, bien que nous n'avons pas appris window.requestAnimationFrame en classe. vous dira comment cela a fonctionné. –

+0

alors, ça a marché! l'animation fonctionne. Mais maintenant, quand j'imprime toutes les autres notes sur le tableau en une seule boucle, seule la dernière affiche. Des idées? 'function PrintAllNotes() { // imprimer toutes les tâches du tableau pour (var i = 0; i

+0

@EranBallili: voir la mise à jour –