網(wǎng)頁(yè)彈出框是一個(gè)比較常見(jiàn)的應(yīng)用,比如在用戶操作界面時(shí)彈出提醒框或者加載框,可以給用戶提示一些信息。瀏覽器的alert()彈出警告框會(huì)中斷用戶操作,顯得不夠友好。我們可以使用原生JS寫一個(gè)彈出框,類似Android的Toast組件。
先分析一下實(shí)現(xiàn)思路:
- 先確定彈出框的樣式,寫出CSS代碼。
- 動(dòng)態(tài)創(chuàng)建元素、設(shè)置元素樣式。
- 控制元素顯示與隱藏。
寫出CSS代碼
根據(jù)想要實(shí)現(xiàn)的效果,比如邊框背景字體圖標(biāo)等,這里寫一個(gè)簡(jiǎn)單的CSS樣式代碼
#toast{
position: absolute;
display: none;
left: 50%;
top: 50%;
z-index: 9999;
margin: auto;
padding: 16px 8px;
transform: translate(-50%,-50%);
min-width: 120px;
height: 25px;
line-height: 40px;
border-radius: 5px;
text-align: center;
color: #fff;
background-color: rgba(0,0,0,0.5);
}
如果想先知道上面的CSS樣式什么樣子,可以將選擇器加入到一個(gè)div中演示,并將display改為block。
封裝組件對(duì)象
后面創(chuàng)建元素和控制元素的事情都是由JS完成的,可以封裝成對(duì)象,再將需要做的事情寫成函數(shù)。
var toast = {}
創(chuàng)建了一個(gè)空對(duì)象,后面根據(jù)需求添加屬性和方法。
因?yàn)樾枰刂骑@示和隱藏,所以使用setTimeout特別合適。初步設(shè)定兩個(gè)需求,一是同一時(shí)間只彈出一個(gè)框,二是自動(dòng)關(guān)閉,以下代碼設(shè)置了三個(gè)方法,一個(gè)屬性。
var toast = {
hideTimeout : null,
init : function(){},
show : function(){},
hide : function(){}
}
后面分別寫出上面方法的實(shí)現(xiàn)代碼
- init 初始化
function () {
var toastNode = document.createElement('div');
toastNode.innerHTML = '<span class="text">默認(rèn)提示</span>';//設(shè)置HTML模板,可以根據(jù)需求設(shè)計(jì)
toastNode.id = 'toast';//設(shè)置id,一個(gè)頁(yè)面有且僅有一個(gè)toast
toastNode.setAttribute('class','toast');// 設(shè)置類名,如果有必要的話
toastNode.style.display = 'none';//設(shè)置隱藏,默認(rèn)隱藏
document.body.appendChild(toastNode);//添加到body下面
}
初始化代碼動(dòng)態(tài)創(chuàng)建了一個(gè)隱藏的toast窗口,設(shè)置了一些屬性
- show 顯示toast
function (text){
if(this.hideTimeout){//判斷當(dāng)前是否有彈出框,有的話先關(guān)閉當(dāng)前
clearTimeout(this.hideTimeOut);
this.hideTimeOut = null;
}
if(!text){//判斷傳入提示文本是否為空,是的話返回
console.log('text為空');
return;
}
var toastNode = document.getElementById('toast');
if (!toastNode) {//判斷toast是否初始化
console.log('未初始化');
return;
}
var toastText = toastNode.querySelector('.text');
toastText.innerHTML = text || '';//找到toast設(shè)置顯示文本
toastNode.style.display = 'block';//設(shè)置toast為顯示狀態(tài)
this.hideTimeout = setTimeout(function(){//timeout設(shè)置多久后隱藏
toastNode.style.display = 'none';
toast.hideTimeout = null;
},2000);
}
上面代碼有些長(zhǎng),但是邏輯都特別清晰,先判斷toast一些狀態(tài),然后顯示再隱藏。
- hide 隱藏并移除toast
function (){
if(this.hideTimeout){//如果當(dāng)前存在toast,就關(guān)閉當(dāng)前toast
clearTimeout(this.hideTimeOut);
this.hideTimeOut = null;
}
var toastNode = document.getElementById('toast');
if (toastNode) {
toastNode.style.display = 'none';//移除toastDOM
document.body.removeChild(toastNode);
}
}
隱藏并移除toast,建議把這部分放在setTimeout中,如果剛初始化就會(huì)隱藏移除的話,toast不會(huì)彈出來(lái)。
完整toast示例代碼
<!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>Document</title>
<style>
#toast{
position: absolute;
display: none;
left: 50%;
top: 50%;
z-index: 9999;
margin: auto;
padding: 16px 8px;
transform: translate(-50%,-50%);
min-width: 120px;
min-height: 25px;
line-height: 25px;
border-radius: 5px;
text-align: center;
color: #fff;
background-color: rgba(0,0,0,0.5);
}
div{
text-align: center;
}
</style>
</head>
<body>
<div><button onclick="myFun()">點(diǎn)我彈出toast</button></div>
<script>
var toast = {
hideTimeout : null,
init : function () {
var toastNode = document.createElement('div');
toastNode.innerHTML = '<span class="text">默認(rèn)提示</span>';//設(shè)置HTML模板,可以根據(jù)需求設(shè)計(jì)
toastNode.id = 'toast';//設(shè)置id,一個(gè)頁(yè)面有且僅有一個(gè)toast
toastNode.setAttribute('class','toast');// 設(shè)置類名,如果有必要的話
toastNode.style.display = 'none';//設(shè)置隱藏,默認(rèn)隱藏
document.body.appendChild(toastNode);//添加到body下面
},
show : function (text){
if(this.hideTimeout){//判斷當(dāng)前是否有彈出框,有的話先關(guān)閉當(dāng)前
clearTimeout(this.hideTimeOut);
this.hideTimeOut = null;
}
if(!text){//判斷傳入提示文本是否為空,是的話返回
console.log('text為空');
return;
}
var toastNode = document.getElementById('toast');
if (!toastNode) {//判斷toast是否初始化
console.log('未初始化');
return;
}
var toastText = toastNode.querySelector('.text');
toastText.innerHTML = text || '';//找到toast設(shè)置顯示文本
toastNode.style.display = 'block';//設(shè)置toast為顯示狀態(tài)
this.hideTimeout = setTimeout(function(){//timeout設(shè)置多久后隱藏
toastNode.style.display = 'none';
toast.hideTimeout = null;
},2000);
},
hide : function (){
if(this.hideTimeout){//如果當(dāng)前存在toast,就關(guān)閉當(dāng)前toast
clearTimeout(this.hideTimeOut);
this.hideTimeOut = null;
}
var toastNode = document.getElementById('toast');
if (toastNode) {
toastNode.style.display = 'none';//移除toastDOM
document.body.removeChild(toastNode);
}
}
}
function myFun(){
toast.init();
toast.show("這是一條提示消息");
setTimeout(toast.hide,2000);
}
</script>
</body>
</html>
條條大路通羅馬,通往廣場(chǎng)的路也不止一條。實(shí)現(xiàn)一個(gè)功能往往會(huì)有多種方法,這里只是給大家一個(gè)參考思路,很多地方還需要優(yōu)化,發(fā)現(xiàn)不足歡迎指出。