原生JS實(shí)現(xiàn)Web彈出層Toast

網(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)不足歡迎指出。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 前言 接觸vue框架也有一個(gè)多月的時(shí)間了,整理下之前做過(guò)的一個(gè)小demo,主要是熟悉vue全家桶技術(shù),界面布局模仿...
    視覺(jué)派Pie閱讀 26,897評(píng)論 20 284
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,688評(píng)論 4 61
  • 用到的組件 1、通過(guò)CocoaPods安裝 2、第三方類庫(kù)安裝 3、第三方服務(wù) 友盟社會(huì)化分享組件 友盟用戶反饋 ...
    SunnyLeong閱讀 15,206評(píng)論 1 180
  • github排名https://github.com/trending,github搜索:https://gith...
    小米君的demo閱讀 4,963評(píng)論 2 38
  • 16宿命:用概率思維提高你的勝算 以前的我是風(fēng)險(xiǎn)厭惡者,不喜歡去冒險(xiǎn),但是人生放棄了冒險(xiǎn),也就放棄了無(wú)數(shù)的可能。 ...
    yichen大刀閱讀 8,205評(píng)論 0 4

友情鏈接更多精彩內(nèi)容