【问题标题】:Fade-In Transition on class change(JS) not working类更改(JS)的淡入转换不起作用
【发布时间】:2017-01-30 13:56:03
【问题描述】:

我正在尝试使用基本的 JS 和 CSS 对更改后的 innerHTML 元素进行淡入处理。

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

附: 我必须使用基本的 JS(没有 JQuery 之类的),因为它是我正在为 FullStack 课程做的一个项目,我们应该只使用我们学到的基础知识。

知道为什么它不起作用吗? 提前谢谢。 :)

【问题讨论】:

    标签: javascript css css-animations transition fadein


    【解决方案1】:

    浏览器可能在 1 次绘制中批处理所有 DOM 指令。因此,所有 div 都会立即应用“淡入”。

    要强制“淡入”仅应用于下一个绘制周期,请使用reqeuestAnimationFrame

    这将导致浏览器看到前状态 (opacity:0) 和后状态 (opacity: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 中的工作方式。即:它泄漏到全局范围。在每次迭代中,这个 same 变量都会被覆盖。由于设置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;
      }
    }
    

    顺便说一句:作为 JS 初学者课程的一部分,必须使用闭包和 window.requestAnimationFrame 并没有让我印象深刻,所以我可能会把你推向错误的方向。不管知道闭包是了解 javascript 的一个非常重要的部分,所以我希望它仍然有帮助。祝你好运!

    1)how do closures work

    【讨论】:

    • 嘿,谢谢你的回答 :) 我会试一试,虽然我们还没有在课堂上学习 window.requestAnimationFrame。会告诉你结果如何。
    • 所以,它成功了!动画作品。但是现在,当我在一个循环中打印数组上的所有其他注释时,只显示最后一个。有任何想法吗 ? function PrintAllNotes() { //print all the tasks in the array for (var i = 0; i &lt; tasksArray.length; i++) { PrintNote(i); } } 再次感谢!
    • 嘿@Geert-Jan 再次感谢您的帮助。我尝试了新方法,得到了和以前一样的结果。它只在数组中的最后一个淡入淡出。如果您添加另一个音符,它会很好地淡入。但是当我刷新页面时,它应该将保存在 localStorage 中的所有内容放入数组中,并打印所有内容。不幸的是,它只显示最后一个。编辑:顺便说一下,noteDivsElement 是一个全局变量。但是当它是函数的本地变量时它也不起作用
    • noteDivsElement 绝对应该是一个全局变量。我已经描述得很清楚了。不知道为什么上面给出的 2 个选项不适合你
    猜你喜欢
    • 1970-01-01
    • 2019-09-24
    • 1970-01-01
    • 2012-01-29
    • 1970-01-01
    • 2012-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多