移動端【監聽物理返回】
<!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>

浙公網安備 33010602011771號