你知道那些當你試圖關閉瀏覽器視窗時出現的煩人彈窗嗎?

它們好像知道你在試圖關閉視窗,就像它們能讀取你的思想一樣。

實際上,這是一個非常簡單的概念,你需要聽取特定的DOM事件。

我個人不推薦使用彈窗,因為我覺得它們很煩人,但是你的公司可能要求你實現一個,所以在這裡我們就來實現一個。

我喜歡保持事情簡單,所以這裡是HTML的部分:

<!doctype html>
<head>
<title>彈窗頁面</title>
</head>
<body>
<div id="popup">
<h3>彈窗!</h3>
</div>
</body>

再來是這部分的CSS:

body {
font-family: system-ui;
background-color: #f6d198;
}

#popup {
position: fixed;
width: 100%;
visibility: hidden;
z-index: 10002;
top: 0;
opacity: 0;
transform: scale(0.5);
transition: transform 0.2s, opacity 0.2s, visibility 0s 0.2s;
position: relative;
margin: 0 auto;
text-align: center;
box-shadow: 0 1px 10px rgba(0, 0, 0, 0.5);
width: 60%;
background: #862a5c;
padding-bottom: 100px;
padding-top: 50px;
color: #fff;
font-size: 2rem;
}

最後是這段JavaScript:

const show = () => {
const element = document.querySelector("#popup")
element.style.visibility = "visible"
element.style.opacity = "1"
element.style.transform = "scale(1)"
element.style.transition = "0.4s, opacity 0.4s"
}

document.addEventListener("DOMContentLoaded", () => {
document.addEventListener("mouseout", (event) => {
if (!event.toElement && !event.relatedTarget) {
setTimeout(() => {
show()
}, 1000)
}
})
})

在Codepen中查看:

See the Pen [滑鼠離開視窗時彈出的彈窗,簡易實現] (https://codepen.io/flaviocopes/pen/gOawyKr) by Flavio Copes ([@flaviocopes] (https://codepen.io/flaviocopes)) 在[CodePen](https://codepen.io)上

頁面應該看起來相當無聊:

無聊的頁面

如果你試圖通過滑鼠進入/離開頁面,你應該會看到一個彈窗出現:

彈窗出現

這是因為我們監聽了mouseout事件,並且在顯示彈窗之前等待了1秒。

一旦你了解了基本知識,你可以開始添加一些花俏的功能,比如按下esc鍵時關閉彈窗:

const hide = () => {
const element = document.querySelector("#popup")
element.style.visibility = "hidden"
element.style.opacity = "0"
element.style.transform = "scale(0.5)"
element.style.transition = "0.2s, opacity 0.2s, visibility 0s 0.2s"
}

document.addEventListener("DOMContentLoaded", () => {
document.onkeydown = event => {
event = event || window.event
if (event.keyCode === 27) {
hide()
}
}
})

以及如果用戶在彈窗外點擊文檔時關閉彈窗:

let eventListener

// 在show()內部
eventListener = document.addEventListener("click", function (clickEvent) {
let el = clickEvent.target
let inPopup = false
if (el.id === 'popup') {
inPopup = true
}
while (el = el.parentNode) {
if (el.id == "popup") {
inPopup = true
}
}
if (!inPopup) hide()
})

// 在hide()內部
if (eventListener) {
document.removeEventListener(eventListener)
}

在Codepen中的示例:

See the Pen [滑鼠離開視窗時彈出的彈窗,使用hide()實現] (https://codepen.io/flaviocopes/pen/abvmrzg) by Flavio Copes ([@flaviocopes] (https://codepen.io/flaviocopes)) 在[CodePen](https://codepen.io)上

現在,一個有趣的事情是將我們顯示彈窗的事實存儲在cookie中,這樣我們只向每個人顯示一次。

這是一種可能的實現方法:我們在顯示彈窗時設置popup=true的cookie,並在再次顯示它之前檢查cookie:

let showed = false;

const show = () => {
if (showed) return;

if (
document.cookie.split(";").filter((item) => {
return item.includes("popup=");
}).length
) {
return;
} else {
console.log(
document.cookie.split(";").filter((item) => {
return item.includes("popup=")
}).length
)
console.log(document.cookie.split(";"))
}

document.cookie = "popup=true;path=/;max-age=15768000"
showed = true

// 剩下的show()代碼