为什么通过AddClass给元素添加关键帧动画会触发整个函数Javascript?

Why Does Adding Keyframe Animation To Element Via AddClass Trigger Entire Function In Javascript?

问题:

当通过 class (elm.addClass) 添加动画而不是简单地更改每个元素的 classes 时,jQuery/JS 为每个有变化的元素运行整个函数共 class.

尝试了很多场景来理解为什么会出现这种行为(即普通 JS、jQuery、多个函数等),结果是可以轻松地让滑块工作(实际上注释掉了代码有效)但为什么代码的行为不符合文档中的规定?它不应该为每个 class 变化触发函数 - 几乎是冒泡类型的效果(或者它可能以某种方式可能吗?如果是这样,为什么?)

简单的解决方案:

当然可以通过 JS 而不是 CSS (elm.fadeOut) 控制动画来避免这种行为,但这并不能解释为什么 JS 表现得好像它有一个错误。

总结:

为什么要通过为每个发生变化的元素添加 class 触发函数(或冒泡效果)来添加动画?每个元素都应在不重新触发功能的情况下设置动画。

let imgnx = 0
function fadeImg() {
  if (imgnx < imgSrc.length) {
    $('#ctnr').append(`<img class='slides show' src=${imgSrc[imgnx]} alt='slide ${imgnx +1}'>`)
    $(`.show:eq(${imgnx})`).on('animationend', function() {
      imgnx = imgnx + 1
      fadeImg()
    })
  } else {
    console.log(`All slides displayed', 'image index is: ${imgnx}`);
    $(".slides").removeClass("show").addClass("hide");
    $(".hide").last().on('animationend', function () {
      // $(".slides").remove(); imgnx = 0; fadeImg();
      $('#ctnr').fadeOut('slow').fadeIn('slow')
    })
    
    console.log('Class removed - class show removed, index is: ' + imgnx)
  }
}

在以下位置测试完整代码: https://playcode.io/351331?tabs=script.js,preview,console

Why Does Adding Keyframe Animation To Element Via AddClass Trigger Entire Function >In Javascript?

这道题的答案由代码结构决定。

首先,以防万一有人不确定,将 CSS 关键帧动画添加到 api 或代码块本身并不 re-trigger JavaScript 功能。虽然如果需要的话,它可以被设计成[结合附加代码]来做到这一点,但它的有机设计并不是为了这样的目的。在这种特殊情况下,通过 class 加法添加 CSS 动画似乎调用了它自己的函数,动画本身并不是在调用函数 [或模拟函数调用],而是这种意外行为的结果不完整的代码。

代码错误

观察运行中的代码时,我们可以很容易地看到导致各种代码块在不希望的情况下触发的意外行为。在进一步检查时,审查员会注意到与此行为相关的特定代码块。如果我们将此代码块归零,我们会发现 EventListener 已打开但从未关闭(在纯 JS 术语中它已添加但从未删除)。这就是问题所在。因为 EventListener 从未被关闭,所以它仍在监听任何动画结束。当额外的动画被添加到被监听的元素时(通过 class 或任何其他方法),EventListener 会按它应该的方式触发,并且处理程序会启动,执行它提供给 运行 的任何代码。这会导致奇怪的行为,似乎是在回忆函数。

解决方案

一旦找到问题代码,解决方案就显而易见了。只需在适当的位置(多个选项)关闭 EventListener,应用程序 运行 就会完美无缺。

建议的示例代码

else { /* Try code below */
// $('.show').off('animationend')
console.log(`All slides displayed', 'image index is: ${imgnx}`);
$(".slides").removeClass("show").addClass("hide");
/* Try code here */ 
// $('.show').off('animationend')
$(".hide").last().on('animationend', function () {
  $(".slides").remove(); imgnx = 0; fadeImg();
  $('#ctnr').fadeOut('slow').fadeIn('slow')
})

结论

是的,有各种变通方法等,但与解决不完整或不正确的代码相比,维护适当的编程标准并实施完整和正确的代码通常要好得多。此外,包含的代码建议仅仅是示例,绝不是可能解决方案的范围。更多的代码交互和无限的解决方案肯定会出现。

但更重要的是,此练习用于展示移除或关闭 EventListeners 的价值。

谢谢。