繁体   English   中英

使用 setTimeout 关闭前一个模态后未打开模态

[英]Modal not opening after closing previous one with setTimeout

我有一个模态,它将以褪色 animation(不透明度 0 到 1)打开,并以相同的 animation(不透明度 1 到 0)关闭。 除了关闭 animation 外,一切正常。 我有一个“淡入淡出”的 class 并使用 JS 来更改“animationName”,具体取决于用户是否关闭/打开模式。 我有 setTimeout 所以关闭 animation 可以执行,并且模态将显示为“无”,否则模态将立即关闭而没有 animation 因为显示将立即执行。

由于 setTimeout 的延迟,每当我关闭模态并立即垃圾邮件单击另一个图像时,模态将不会打开,直到 setTimeout 的延迟由于某种原因完成。 但是,如果我在模态关闭并单击另一个图像后只等待一秒钟,它就会打开。

实现 animation 以打开/关闭我的模态可能有更好的方法,但这是我唯一可以开始工作的方法。 对实现 animation 的新想法持开放态度,谢谢!

这是一个解释我的问题的视频。 https://streamable.com/jflu55

https://jsfiddle.net/Boros/kseaoz1h/4/

"use strict";

const $ = selector => document.querySelector(selector);
const $all = selector => document.querySelectorAll(selector);

const gallery = $all("#gallery img, #gallery .video_container");
console.log(gallery.length);

const slides = $all("#my_modal div");
console.log(slides.length);

const closeModal = evt => {
    // Loops to find the slide that the user clicked on if needed
    for ( let i in slides ) {
        /* Checks the correct slide container the user clicked against the index of the slides.
         Loops until it finds it, or if clicked the close button */
        if ( evt.target == slides[i] || evt.target == $("#close_button") ) {

            $(".fade").style.animationName = "fadeOut";

            // Closes modal after animation finishes
            setTimeout( () => {
                $("#my_modal").style.display = "none";

                /* Will set the display of all the slides to none no matter what 
                in order to prevent undefined errors when clicking the close button */
                for (let i = 0; i < slides.length; i++) {
                    slides[i].style.display = "none";
                }
            }, 1998);
            
            // Allows page to be scrollable
            $("body").style.overflow = "initial";
        
            // Allows images to be tab accessible
            for (let i = 0; i < gallery.length; i++) {
                gallery[i].setAttribute("tabindex", "1");
            }

            const videos = $all(".video_slides video");
            // Will pause the video when you close out of the modal
            for (let p = 0; p < videos.length; p++) {
                videos[p].pause();
            }
        }
    }
}

const openModal = evt => {
    // Loops to find the index of the image or video that the user clicked on
    for ( let i in gallery ) {
        /* Checks the image or video the user clicked against the index of the gallery.
         Loops until it finds it */
        if ( evt.currentTarget == gallery[i] ) {
            // Prevents page from being scrollable inside the modal
            $("body").style.overflow = "hidden";

            // Prevents images inside #gallery from being tabbed to 
            for (let t = 0; t < gallery.length; t++) {
                gallery[t].removeAttribute("tabindex");
            }

            $("#my_modal").style.display = "initial";

            // Opening animation for modal
            $(".fade").style.animationName = "fadeIn";

            
            // Displays the correct image or video
            slides[i].style.display = "initial";

            // Closes modal when clicked outside the image
            slides[i].addEventListener("click", closeModal);
        }
    }
}

gallery.forEach(item => {
    item.addEventListener('click', evt => {
        openModal(evt);
    })
})

gallery.forEach(item => {
    item.addEventListener('keyup', evt => {
        if ( evt.keyCode == 13 ) {
            openModal(evt);
        }
    });
})

$("#close_button").addEventListener("click", closeModal);

$("#close_button").addEventListener("keyup", evt => {
    if ( evt.keyCode == 13 ) {
        closeModal(evt);
    }
});
@keyframes fadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}
@keyframes fadeOut {
    from { opacity: 1; }
    to { opacity: 0; }
}
.fade {
    animation-duration: 2s;
}
#my_modal {
    display: none;
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 9999;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.4);
    overflow: auto;
    margin: 0;
    padding: 0;
    -moz-user-select: none;
    -webkit-user-select: none;
    -ms-user-select: none;
    user-select: none;
}
.img_slides, .video_slides {
    display: none;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    padding: 0;
    margin: 0;
    width: 100%;
    height: 100%;
}

编辑:我发现我的问题只有在您点击关闭图像不在的区域中的另一个图像时才会出现。如果您点击关闭图像所在的另一个图像,它不会发生。

我的问题是由于垃圾邮件点击导致 setTimeout 延迟被重置,因为每次我在图像外部点击时都会触发 eventListener。

一旦用户在图像外部单击以关闭模式,我就删除了 eventListener,这可以防止 setTimeout 延迟被重置,从而解决了问题。

// Prevents  setTimeout delay from resetting due to spam clicking outside the image

slides[i].removeEventListener("click", closeModal);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM