如何使用CSS和JS同时给多个模态添加进出过渡效果?

How to add in- and -out transition effect to multiple modals at once using CSS and JS?

第一个 post,所以希望它足够清楚。

我的任务是创建一个覆盖页面上 multi-column/-row 网格布局的模态对象。模态应该出现在特定网格项目的悬停上。当模态出现时,网格区域的背景应该变暗。我被要求不要使用任何额外的库(例如,jQuery)。

为了完成这项任务,我添加了两个模态对象,一个用于实际模态 window,另一个用于调光器对象。我无法让 CSS 悬停在有问题的项目悬停时对两个对象都起作用,所以我使用 JavaScript 添加 CSS 更改。

过渡效果适用于过渡效果,但不适用于过渡效果。我想我想多了这个任务所以感谢任何建议。

<style type="text/css">

    .container {
        width: 100vw;
        height: 100vh;
        display: grid;
        grid-template-columns: repeat(4, 1fr);
        grid-template-rows: repeat(3, 1fr);
        grid-gap: 10px;
        margin: 0;
        padding: 0;
    }

    .column {
        background-color: hsl(0,80%,70%);
    }

    #modal_maker {
        font-size: 5vw;
        height: 100%; 
        width:100%;
        display:flex;
        align-items: center;
        justify-content: center;
    }

    #modal_maker, #modal {
        z-index: 2;
    }

    #modal {
        visibility: hidden;

        background-color: hsl(200,50%,70%);

        width: 80%;
        height: 80%;

        position: absolute;

        margin: auto;

        top: 0; left: 0; bottom: 0; right: 0;

        opacity: 0;
        transition: opacity 1s;
    }

    #background-dimmer {
        visibility: hidden;

        background-color: black;

        width: 100%;
        height: 100%;

        position: absolute;

        z-index: 1;

        opacity: 0;
        transition: opacity 0.5s;
    }

</style>

<body>
<div class="container">

    <div class="column"></div>
    <div class="column"></div>
    <div class="column"></div>
    <div class="column"></div>
    <div class="column"></div>
    <div class="column"></div>
    <div class="column"></div>
    <div class="column" id="modal_maker">Hover Here</div>
    <div class="column"></div>
    <div class="column"></div>
    <div class="column"></div>
    <div class="column"></div>

    <div id="modal"></div>
    <div id="background-dimmer"></div>

</div>

<script type="text/javascript">

document.querySelector(".container").addEventListener("mouseover", function(el) {
        if (el.target.id=="modal_maker" || el.target.id=="modal") {

            document.getElementById("modal").style.cssText = "visibility:visible; opacity: 1;"
            document.getElementById("background-dimmer").style.cssText = "visibility:visible; opacity: 0.75;"
        } else {
            document.querySelectorAll("#modal, #background-dimmer").forEach(x => x.style.cssText="opacity: 0; visibility:hidden;")
        }
    })

</script>
</body>

都是因为visibility:hidden

在 js 中

...
} else {
        document.querySelectorAll("#modal, #background-dimmer").forEach(x => x.style.cssText="opacity: 0; visibility:hidden;")
}
...

您可以立即将 opacity 更改为 0,还可以将 visibility:hidden 更改为 visibility:hidden,因此没有时间进行转换,当代码触发元素时立即隐藏。

您使用 cssText 更改元素的属性,因此当您将鼠标移到另一个元素上时 visibility:visible 将不会出现,取而代之的是 visibility:hidden 来自 css(所以你也需要删除它)。

我知道它会导致 #modal 捕获鼠标悬停事件...这就是要解决的问题

我不知道这个解决方案是否是故意在你只 mouseover 其他元素时隐藏模态,如果我将鼠标完全从 table 离开,模态将保留。 .. 只是想提一下也许它不相关。

我根据你的代码做了fiddle:https://jsfiddle.net/svh6dpfk/1/

修复此#modal 捕获事件的一个想法是添加适当的可见性作为回调(有 transitionend 事件将在动画完成时捕获瞬间,所以这样的事情会有所帮助:

document.querySelector("#modal, #background-dimmer").addEventListener("transitionend", function(el) {

  if(parseFloat(el.target.style.opacity) > 0){
    el.target.style.cssText = "visibility:visible;opacity:1";
    alert("animation end visible");
  }else{
    el.target.style.cssText = "visibility:hidden;opacity:0";
    alert("animation end unvisible");
  }

});

更新

它现在对我有用...

有点棘手,您的 css 需要 visibility:hidden 模态和 background-dimmer(就像您的代码一样) 这似乎对我有用:

document.querySelector(".container").addEventListener("mouseover", function(el) {
    if (el.target.id=="modal_maker" || el.target.id=="modal") {

        document.getElementById("modal").style.cssText = "visibility:visible;opacity: 1;"
        document.getElementById("background-dimmer").style.cssText = "visibility:visible;opacity: 0.75;"
    } else {
        if(document.getElementById("modal").style.opacity == "1"){
        document.querySelectorAll("#modal, #background-dimmer").forEach(x => x.style.cssText="visibility:visible;opacity: 0; ")
        }
        /* alert("should be on leave") */;
    }
})

这部分 .forEach(x => x.style.cssText="visibility:visible;opacity: 0; ") 更改是因为您的 css 始终 visibility:hidden,因此您需要始终在 visible.

上执行转换

完整示例: https://jsfiddle.net/Loary65w/1/

您需要记住拥有跨浏览器支持,您需要涵盖所有这些事件 webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend

希望对您有所帮助。也许有更好的解决方案更简单,我把那个复杂化了:F