Как добавить эффект перехода in-and-out к нескольким модалам одновременно, используя CSS и JS? - PullRequest
0 голосов
/ 07 мая 2019

Первый пост, так что, надеюсь, он достаточно понятен.

Мне было поручено создать модальный объект, который перекрывает многостолбцовый / строчный макет сетки на странице. Модал должен появиться при наведении на определенный элемент сетки. Когда появляется модальное изображение, фон области сетки должен тускнеть. Меня попросили не использовать никаких дополнительных библиотек (например, jQuery).

Чтобы выполнить эту задачу, я добавил два модальных объекта, один для реального модального окна, а другой для объекта диммера. Мне не удалось заставить 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>

1 Ответ

0 голосов
/ 07 мая 2019

Все из-за visibility:hidden

в js

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

мгновенно вы изменяете opacity на 0, но также visibility:hidden, поэтому нет времени для перехода, сразу же, когда элемент кода запускает скрытие.

Вы используете cssText, чтобы изменить свойства элемента, чтобы visibility:visible не было там, когда вы наводите мышь на другой элемент, вместо этого будет visibility:hidden из css (так что вам также нужно удалить это) .

Я знаю, что это #modal захватывает событие наведения мыши, тогда ... вот в чем проблема выяснить

Я не знаю, нацелено ли это решение на то, чтобы скрыть модал, когда вы mouseover только другой элемент, что если я оставлю мышь целиком со стола, модал останется ... просто хотел упомянуть, может быть, его не подходит.

Я сделал скрипку на основе вашего кода: 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 для модального и фонового затемнения (как в вашем коде) мне кажется, это работает:

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

...