移动端【监听物理返回】

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>checkout</title>
    <style>
        .stream-discount {
            word-spacing: 0;
            letter-spacing: 0;
            width: 100%;
            height: 100%;
            position: fixed;
            top: 0;
            left: 0;
            z-index: 1001;
            background-color: #00000099;
        }
        .backDialogContainer{
            position: fixed;
            width: 80%;
            left: 50%;
            transform: translateX(-50%);
            top: 30%;
        }
        .backDialogContent{
            background-color: white;
            border-radius: 20px;
            padding: 20px;
            display: flex;
            flex-direction: column;
            align-items: center;
        }
        .backDialogContent .backDialogIcon{
            padding: 10px 0;
        }
        .backDialogContent .backDialogIcon img{
            width: 52px;
            height: 52px;
            margin: 0 auto;
            display: block;
        }
        .backDialogContent .backDialogText{
            font-size: 26px;
            font-weight: 600;
            color: #222;
            text-align: center;
        }
        .backDialogContent .backDialogBtn1{
            background-color: #FFB518;
            width: 239px;
            text-align: center;
            margin: 20px auto 0;
            display: block;
            color: #fff;
            font-size: 18px;
            font-weight: 600;
            height: 48px;
            line-height: 48px;
            border-radius: 12px;
            border: none;
            cursor: pointer;
        }
        .backDialogContent .backDialogBtn2{
            background-color: #fff;
            width: 239px;
            text-align: center;
            margin: 20px auto 0;
            display: block;
            color: #A9A9A9;
            font-size: 18px;
            font-weight: 600;
            height: 48px;
            line-height: 48px;
            border-radius: 12px;
            border: none;
            cursor: pointer;
        }
        .closeBtnStyle{
            position: absolute;
            bottom: -70px;
            left: 50%;
            transform: translateX(-50%);
            width: 50px;
            height: 50px;
            border-radius: 50%;
            display: flex;
            justify-content: center;
            align-items: center;
            cursor: pointer;
        }
        .closeBtnStyle img{
            width: 100%;
            height: 100%;
        }

    </style>
</head>
<body>
    <h1>点击返回试试</h1>
    <script>
        const StreamDiscount = (function() {
            const config = {
                action_log: 2,
                discount_value: 0,
                ga: "",
                intercept: 2,
                intercept_log: 2
            };
           
            const DeviceDetector = {
                isMobile() {
                    return null !== navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone|HUAWEI)/i);
                },
                isFBIOS() {
                    return navigator.userAgent.indexOf("FB") > -1 && navigator.userAgent.indexOf("iOS") > -1;
                }
            };
           
            const HistoryManager = {
                pushState() {
                    window.history.pushState(
                        Object.assign(window.history.state || {}, { key: "his-push-01" }),
                        "",
                        "#1"
                    );
                }
            };
           
            const ModalManager = {
                show() {
                    if (document.querySelector(".stream-discount")) return;
                    const modalElement = document.createElement("div");
                    modalElement.setAttribute("class", "stream-discount");
                    modalElement.innerHTML = `
                        <div class="backDialogContainer">
                            <div class="backDialogContent">
                                <div class="backDialogIcon"><img src="./img/rivet-icons_exclamation-mark-circle.png"></div>
                                <h3 class="backDialogText">このページを離れても宜しいですか?</h3>
                                <button class="closeBtn backDialogBtn1" type="button">サイトを閲覧する</button>
                                <button class="backDialogBtn2" type="button">残酷な出発</button>
                            </div>
                            <div class="closeBtn closeBtnStyle">
                                <img src="./img/iconoir_delete-circle.png"></img>
                            </div>
                        </div>
                    `;
                   
                    document.body.appendChild(modalElement);
                    document.body.classList.add("stream-modal-show");
                    this.bindCloseEvent();
                    this.bindGoHistoryEvent();
                },
                               
                bindCloseEvent() {
                    const closeBtns = document.querySelectorAll(".closeBtn");
                    if (!closeBtns || closeBtns.length === 0) return;
                   
                    closeBtns.forEach(function(btn) {
                        btn.addEventListener("click", function() {
                            const mainElement = document.querySelector(".stream-discount .backDialogContainer");
                            if (mainElement) {
                                mainElement.style.cssText = "top: -100%; opacity: 0;";
                            }
                            setTimeout(function() {
                                const modal = document.querySelector(".stream-discount");
                                if (modal) modal.remove();
                                document.body.classList.remove("stream-modal-show");
                            }, 250);
                        });
                    });
                },
                bindGoHistoryEvent() {
                    const backBtn = document.querySelector(".backDialogBtn2");
                    if (!backBtn || backBtn.length === 0) return;
                    // 监听返回事件,直接返回上一页
                    backBtn.addEventListener("click", function() {
                        window.removeEventListener("popstate", window.streamIntercept);
                        history.go(-1);
                    });
                }

            };
           
            // 拦截器模块
            const InterceptManager = {
                init(t, e, n) {
                    if (DeviceDetector.isFBIOS() ? "FBIOS" : "OTHER" === "FBIOS") {
                        this.handleFBIOS(t, e, n);
                    } else {
                        this.handleNormal(t, e, n);
                    }
                },
               
                handleFBIOS(t, e, n) {
                    let startX, startY, endX, endY, deltaX, deltaY;
                   
                    if (t && e) {
                        window.scrollTo(0, 5);
                       
                        document.addEventListener("touchstart", function(event) {
                            startX = event.touches[0].clientX;
                            startY = event.touches[0].clientY;
                        });
                       
                        document.addEventListener("touchend", function(event) {
                            const scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
                            endX = event.changedTouches[0].clientX;
                            endY = event.changedTouches[0].clientY;
                            deltaX = endX - startX;
                            deltaY = endY - startY;
                           
                            if (deltaY > 14 && Math.abs(deltaY) > Math.abs(deltaX) && scrollTop <= 0) {
                                ModalManager.show();
                            }
                        });
                    }
                },
               
                handleNormal(t, e, n) {
                    let popCount = 0;
                   
                    if (t && e) {
                        HistoryManager.pushState();
                        ModalManager.show();
                        window.addEventListener("popstate", window.streamIntercept);
                    }
                }
            };
            // 触发器模块
            const TriggerManager = {
                init() {
                    if (!DeviceDetector.isMobile()) {
                        // PC端: 鼠标离开顶部区域触发
                        document.documentElement.addEventListener("mouseleave", function mouseLeaveHandler(event) {
                            if (event.clientY <= 20) {
                                ModalManager.show();
                                document.documentElement.removeEventListener("mouseleave", mouseLeaveHandler);
                            }
                        });
                    } else {
                        // 移动端: 返回拦截触发
                        HistoryManager.pushState();
                       
                        window.streamIntercept = function() {
                            ModalManager.show();
                            window.removeEventListener("popstate", window.streamIntercept);
                        };
                       
                        window.addEventListener("popstate", window.streamIntercept);
                    }
                }
            };
           
            // 公共接口
            return {
                init() {
                    const shouldLog = 1 === config.intercept_log;
                    const shouldIntercept = 1 === config.intercept;
                    const discountValue = Math.abs(config.discount_value);
                    InterceptManager.init(shouldLog, shouldIntercept, discountValue);
                    TriggerManager.init();
                }
            };
        })();

        // 初始化
        StreamDiscount.init();
    </script>
</body>
</html>
posted @ 2022-11-22 13:56  chengJun—  阅读(27)  评论(0)    收藏  举报