CSS过渡不适用于Javascript

托林

我确定我在这里犯了一个菜鸟错误,但是我整天都在研究这种解决方案,而且我似乎无法理解为什么我的以下代码无法正常工作。

用例是一个按钮,用于打开半透明叠加层中的模式框,该叠加层覆盖屏幕上的所有其他内容,包括打开它的按钮。该按钮当前可以很好地打开模态和叠加层,并且单击模态框之外的任何位置确实可以将其关闭。但是我不明白为什么我设置的CSS过渡无法正常工作。

我对此不知所措,因此,我非常感谢经验丰富的开发人员可以提供的任何建议。提前非常感谢您!

最好,乔希

var modalOverlay = document.getElementById('modalOverlay');
var modalButton = document.getElementById('modalButton');

modalButton.addEventListener('click', openModal);
window.addEventListener('click', closeModal);

function openModal() {
    modalOverlay.style.display = "flex";
    modalOverlay.style.opacity = "1";
}

function closeModal(event) {
    if (event.target == modalOverlay) {
        modalOverlay.style.opacity = "0";
        modalOverlay.style.display = "none";
    }
}
.modal-overlay {
    display: none;
    opacity: 0;
    position: fixed;
    top: 0;
    left: 0;
    z-index: 10;
    width: 100vw;
    height: 100vh;
    align-items: center;
    justify-content: center;
    background-color: rgba(0,0,0,0.5);
    transition: all 1s ease-in-out;
}
.modal-box {
    width: 200px;
    height: 200px;
    background-color: blue;
}
<button id="modalButton" class="modal-button">Open Modal</button>
<div id="modalOverlay" class="modal-overlay">
    <div id="modalBox" class="modal-box"></div>
</div>

零298

display不是可以转换的属性。您需要使动画采取多个步骤。当您单击按钮时,应该制作模态flex,但是它仍然应该是透明的。然后,您需要将不透明度转换为1,这是CSS转换可以做到的。

每当关闭模态时,都需要进行逆运算。转换回不透明度0,转换完成后,将其标记为display: none

var modalOverlay = document.getElementById('modalOverlay');
var modalButton = document.getElementById('modalButton');

modalButton.addEventListener('click', openModal);
window.addEventListener('click', closeModal);

function openModal() {
    // This will cause the browser to know 
    // that the element is display flex for a frame
    requestAnimationFrame(() => {
        modalOverlay.classList.add("modal-overlay--open");
        
        // Then when we wait for the next frame
        // the browser will now know that it needs 
        // to do the transition.  If we don't make
        // them separate actions, the browser
        // will try to optimize the layout and skip
        // the transition
        requestAnimationFrame(() => {
            modalOverlay.classList.add("modal-overlay--open-active");
        });
    });
}

function closeModal(event) {
    if (event.target == modalOverlay) {
        modalOverlay.classList.remove("modal-overlay--open-active");
        setTimeout(() => {
          modalOverlay.classList.remove("modal-overlay--open");
        }, 1100);
    }
}
.modal-overlay {
    display: none;
    opacity: 0;
    position: fixed;
    top: 0;
    left: 0;
    z-index: 10;
    width: 100vw;
    height: 100vh;
    align-items: center;
    justify-content: center;
    background-color: rgba(0,0,0,0.5);
    transition: all 1s ease-in-out;
}

.modal-overlay.modal-overlay--open {
    display: flex;
}

.modal-overlay.modal-overlay--open-active {
    opacity: 1;
}

.modal-box {
    width: 200px;
    height: 200px;
    background-color: blue;
}
<button id="modalButton" class="modal-button">Open Modal</button>
<div id="modalOverlay" class="modal-overlay">
    <div id="modalBox" class="modal-box"></div>
</div>


让我们从其他框架如何处理这些过渡中得出一些见解。例如,Vue.js将其输入/离开转换分为6种阶段:

  1. 输入:开始状态,在输入之前添加(对您来说,display: flex并且完全透明
  2. 输入活动状态:设置过渡“目标”的过渡状态(在您的情况下,不透明度为1)
  3. 输入到:过渡完成后应该是什么(我们不会为此烦恼)
  4. 离开:即将开始离开(这里真的不需要更改)
  5. 保持活动状态:设置元素的目标状态,使其知道要转换到的状态(对我们来说,我们只删除表示不透明度的类:1)
  6. 离开:我们也​​不需要

我们需要考虑的主要问题是,我们需要浏览器在页面中具有该元素并“对其进行渲染”,以便它将用于过渡。这就是为什么在示例中添加modal-overlay--open创建它类的原因flex然后,我们仅等待一秒钟,然后添加转换目标类modal-overlay--open-active,这将导致元素实际转换。

然后我们反过来做同样的事情:删除,modal-overlay--open-active以便浏览器知道将元素转换回“常规”样式。我们设置了超时以display: flex在转换完成后删除该类。您可以为此使用事件侦听器,但是对于这样的示例来说,这是过分的。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章