2017-01-30 1 views
0

Я пытаюсь сделать постепенное изменение в измененном innerHTML элементе с использованием базовых JS и CSS.Fade-In Переход на смену класса (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 краске. Поэтому все divs немедленно получают «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; 
    } 
} 

РЕДАКТИРОВАТЬ

в соответствии с комментарием, выше, следует назвать в цикле. Необходимо поэтому убедитесь, чтобы иметь надлежащее закрытие на noteDivsElement (1)

Чтобы объяснить немного подробнее: если бы вы были сделать console.log(noteDivsElement) после тела функции переменной noteDivsElement все равно будет установлена. Это, вероятно, противоречит интуиции, но именно так работают vars в javascript. I.Э .: он протекает в глобальном масштабе. На каждой итерации этот такой же переменная перезаписывается. Так как установка 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

так, это сработало! анимация работает. Но теперь, когда я печатаю все остальные заметки в массиве в одном цикле, отображается только последний. Любые идеи? Функция function PrintAllNotes() { // печать всех задач в массиве для (var i = 0; i

+0

@EranBallili: см. Обновленный ответ –

Смежные вопросы