2017-01-30 14 views
0

基本的なJSとCSSを使用して、変更されたinnerHTMLの要素にフェードを適用しようとしています。フェードインクラス変更の遷移(JS)が機能しない

これは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; 
    } 
} 

これは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; 
} 

P.S. 基本的なJS(JQueryなどはありません)を使用する必要があります。なぜなら、私はFullStackコースのためのプロジェクトであり、私たちが学んだ基礎だけを使うことになっているからです。

なぜそれが機能しないのでしょうか? ありがとうございます。 :)

答えて

0

ブラウザーは、おそらくすべてのDOM命令を1ペイントでバッチ処理しています。したがって、すべてのdivは即座に 'fadeIn'を適用します。

'fadeIn'を強制的に次のペイントサイクルで適用するには、reqeuestAnimationFrameを使用します。

これは前の状態を見ブラウザになります(不透明度:0)とした後、状態(不透明度:1)。その結果、遷移がでキックします

のような何か:

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; 
    } 
} 
コメントを1として

EDIT

、上記ループ内で呼び出す必要があります。したがって、もう少し詳細に説明するためにnoteDivsElement(1)

に適切な閉鎖を持っていることを確認する必要があります:あなたは、変数noteDivsElementはまだ設定されます、関数本体の後console.log(noteDivsElement)を行うとしたら。これはおそらく直感的ではありませんが、javascriptで変数がどのように機能するかだけです。私はグローバルな範囲に漏れています。各反復でこの同じ変数が上書きされます。 fadeInの設定が遅れているので、fadeInのすべての割り当てはループの後に発生し、したがってすべて最新のnoteDivsElementの割り当てに対して発生します。

これはJavaScriptで多く発生する問題です。多くの場合、ループと非同期操作が結合されます。

デフォルトの方法は、関数の引数に変数をバインドするクロージャを作成し、ループが終了した後でもコンテキストの一部として使用できるようにすることです。説明が難しいので、一番下のリンクをお読みください。

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; 
    } 
} 

同じことを達成するために別のES6-の方法は、について話しましたすべての問題を回避let代わりのvarを使用して、適切なローカル変数を使用しています。これはまだかかわらず、すべてのブラウザでサポートされていません。

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; 
    } 
} 

ところで:クロージャを使用することとwindow.requestAnimationFrameはもちろんので、私は間違った方向にあなたをプッシュしている可能性があるJS初心者の一部として私に当たりません。関係なく、クロージャを知っていることは、javascriptを知る上で本当に重要な部分です。がんばろう!

1)how do closures work

+0

ねえ、私たちはクラスでwindow.requestAnimationFrame学んでいないのに、私は、これを試してみるよ:) に答えるためのおかげで。それがどのように機能するか教えてくれます。 –

+0

だから、うまくいった! アニメーションが動作します。 しかし、今では、配列の他のすべてのノートを1つのループで印刷すると、最後のものだけが表示されます。 アイデア 'function PrintAllNotes(){ //(var i = 0; i

+0

@EranBallili:更新された回答を参照 –

関連する問題