CSS过渡不适用于Javascript

时间:2019-12-10 21:02:44

标签: javascript css css-transitions

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

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

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

最好, 乔什

np.save('M.npy', np.random.randn(5,5,5))  # create some dummy matrix
M = np.load('M.npy', mmap_mode='r+')  # load such matrix as a memmap
M[[0,1,2],[1,2,3],[2,3,4]] = 0
M.flush()  # make sure thing is updated on disk
del M
M = np.load('M.npy', mmap_mode='r+')  # re-load matrix
print(M[[0,1,2],[1,2,3],[2,3,4]])  # should show array([0., 0., 0.])
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;
}

2 个答案:

答案 0 :(得分:0)

display属性不能与transition一起使用。相反,只需在opacity 1和0之间切换即可。

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

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

function openModal() {
  modalOverlay.style.opacity = "1";
  modalButton.style.opacity = "0";
}

function closeModal(event) {
  if (event.target == modalOverlay) {
    modalOverlay.style.opacity = "0";
    modalButton.style.opacity = "1";
  }
}
.modal-overlay {
  opacity: 0;
  width: 100vw;
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: rgba(0, 0, 0, 0.5);
}

.modal-overlay,
.modal-button {
  transition: opacity 1s ease-in-out;
}

.modal-box {
  width: 200px;
  height: 200px;
  background-color: blue;
}

.modal-button {
  position: absolute;
  z-index: 2;
}
<button id="modalButton" class="modal-button">Button</button>
<div id="modalOverlay" class="modal-overlay">
  <div id="modalBox" class="modal-box"></div>
</div>

答案 1 :(得分:0)

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

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

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