欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

如何用原生js寫一個彈窗消息提醒插件

1.分析

成都創(chuàng)新互聯(lián)公司一直秉承“誠信做人,踏實(shí)做事”的原則,不欺瞞客戶,是我們最起碼的底線! 以服務(wù)為基礎(chǔ),以質(zhì)量求生存,以技術(shù)求發(fā)展,成交一個客戶多一個朋友!為您提供成都網(wǎng)站建設(shè)、網(wǎng)站建設(shè)、成都網(wǎng)頁設(shè)計(jì)、小程序開發(fā)、成都網(wǎng)站開發(fā)、成都網(wǎng)站制作、成都軟件開發(fā)、app開發(fā)定制是成都本地專業(yè)的網(wǎng)站建設(shè)和網(wǎng)站設(shè)計(jì)公司,等你一起來見證!

當(dāng)消息被觸發(fā)的時候,會有一個自上而下的淡入過程。
在持續(xù)了一段時間后會自動的消失,或者是需要用戶來手動的點(diǎn)擊關(guān)閉按鈕。
在消息消失的時候,會有一個自下而上的淡出過程。
消息是可以疊加彈出的,最新的消息會排在消息列表的最后面。
當(dāng)前面的消息消失后,后面的消息會有一個向上滑動效果。
然后消息本身是有三部分組成

消息圖標(biāo),用來區(qū)分不同類型的消息。
消息文本。
關(guān)閉按鈕,并不是所有消息都需要關(guān)閉按鈕。

2. 實(shí)現(xiàn)樣式

那么,不管我們是用原生js還是vue,首先呢,我們都需要把這個消息的基本樣式給寫出來,然后再通過js來控制消息的彈出和關(guān)閉。
所以,我們先來寫html和css。

<!-- message.html -->
 <!-- 這個css是我引用阿里的一些字體圖標(biāo),請戳: https://www.iconfont.cn/ -->
<link rel="stylesheet" >
<link rel="stylesheet" href="./message.css" rel="external nofollow" >
<script src="./message.js"></script>
 <!-- 消息外層容器,因?yàn)橄⑻嵝鸦旧鲜侨值?,所以這里用id,所有的彈出消息都是需要插入到這個容器里邊的 -->
<div id="message-container">
 <div class="message">
 <!-- 消息圖標(biāo) icon icon-success對應(yīng)我的阿里字體圖標(biāo)的font-class -->
 <div class="type icon icon-success"></div>
 <!-- 消息文本 -->
 <div class="text">這是一條正經(jīng)的消息~</div>
 <!-- 關(guān)閉按鈕 -->
 <div class="close icon icon-close"></div>
 </div>
 <div class="message">
 <div class="type icon icon-error"></div>
 <div class="text">這是一條正經(jīng)的消息~</div>
 </div>
</div>
/* message.css */
 #message-container {
 position: fixed;
 left: 0;
 top: 0;
 right: 0;
 /* 采用flex彈性布局,讓容器內(nèi)部的所有消息可以水平居中,還能任意的調(diào)整寬度 */
 display: flex;
 flex-direction: column;
 align-items: center;
}
#message-container .message {
 background: #fff;
 margin: 10px 0;
 padding: 0 10px;
 height: 40px;
 box-shadow: 0 0 10px 0 #eee;
 font-size: 14px;
 border-radius: 3px;
 /* 讓消息內(nèi)部的三個元素(圖標(biāo)、文本、關(guān)閉按鈕)可以垂直水平居中 */
 display: flex;
 align-items: center;
}
#message-container .message .text {
 color: #333;
 padding: 0 20px 0 5px;
}
#message-container .message .close {
 cursor: pointer;
 color: #999;
}
 /* 給每個圖標(biāo)都加上不同的顏色,用來區(qū)分不同類型的消息 */
#message-container .message .icon-info {
 color: #0482f8;
}
#message-container .message .icon-error {
 color: #f83504;
}
#message-container .message .icon-success {
 color: #06a35a;
}
#message-container .message .icon-warning {
 color: #ceca07;
}
#message-container .message .icon-loading {
 color: #0482f8;
}

3. 實(shí)現(xiàn)動畫

接下來要做的就是這個消息的彈出和消失動畫,我們還是用css來實(shí)現(xiàn)。

想要在css里邊實(shí)現(xiàn)自定義的動畫,首先需要用@keyframes來定義一個動畫規(guī)則,然后再通過animation屬性把動畫應(yīng)用到某個元素上就可以了。
所謂的動畫規(guī)則其實(shí)就是一個動畫序列,或者可以理解為一個個的關(guān)鍵幀,而關(guān)鍵幀的內(nèi)部就是你想改變的css屬性,你可以在關(guān)鍵幀里邊寫上幾乎任何的css屬性,當(dāng)動畫被應(yīng)用的時候,這些css屬性就會根據(jù)各個關(guān)鍵幀做出相應(yīng)的變換。

那我們先用@keyframes來寫一個動畫規(guī)則吧

/* message.css */
 /* 這個動畫規(guī)則我們就叫做message-move-in吧,隨后我們會用animation屬性在某個元素上應(yīng)用這個動畫規(guī)則。 */
@keyframes message-move-in {
 0% {
 /* 前邊分析過了,彈出動畫是一個自上而下的淡入過程 */
 /* 所以在動畫初始狀態(tài)要把元素的不透明度設(shè)置為0,在動畫結(jié)束的時候再把不透明度設(shè)置1,這樣就會實(shí)現(xiàn)一個淡入動畫 */
 opacity: 0;
 /* 那么“自上而下”這個動畫可以用“transform”變換屬性結(jié)合他的“translateY”上下平移函數(shù)來完成 */
 /* translateY(-100%)表示動畫初始狀態(tài),元素在實(shí)際位置上面“自身一個高度”的位置。 */
 transform: translateY(-100%);
 }
 100% {
 opacity: 1;
 /* 平移到自身位置 */
 transform: translateY(0);
 }
}

然后我們再定義一個和message元素同級的類move-in,把message-move-in這個動畫規(guī)則給應(yīng)用到move-in類上,這樣我們需要讓哪個消息彈出,就只需要在消息的類上加一個move-in就行。

/* message.css */
 #message-container .message.move-in {
 /* animation屬性是用來加載某個動畫規(guī)則 請參考 https://developer.mozilla.org/zh-CN/docs/Web/CSS/animation */
 animation: message-move-in 0.3s ease-in-out;
}

可以看到,只需要在某個message上追加一個move-in就能實(shí)現(xiàn)彈出動畫。
那么,消失動畫也是一個套路,只不過跟彈出動畫反過來而已。

/* message.css */
 @keyframes message-move-out {
 0% {
 opacity: 1;
 transform: translateY(0);
 }
 100% {
 opacity: 0;
 transform: translateY(-100%);
 }
}
 #message-container .message.move-out {
 animation: message-move-out 0.3s ease-in-out;
 /* 讓動畫結(jié)束后保持結(jié)束狀態(tài) */
 animation-fill-mode: forwards;
}

animation-fill-mode: forwards;這個是干嘛的呢?因?yàn)閯赢嫿Y(jié)束后默認(rèn)會回到元素的最初狀態(tài),在這里表現(xiàn)的是消失后又出現(xiàn)了。 

所以animation-fill-mode: forwards;是為了讓動畫結(jié)束后保持這個結(jié)束狀態(tài),也就是不在顯示了。

4. 編寫js插件

那么,在寫js之前呢,我們先來思考一下,如果你是插件的使用者,你想怎么來調(diào)用這個插件?
我們的插件很簡單,就是在需要的時候彈出一個消息,假設(shè)插件他提供給我們的是一個類,就叫做Message吧,并且他內(nèi)部有一個show方法,那么只要使用者實(shí)例化這個類后,調(diào)用他的show方法,然后傳入不同的參數(shù)就可以彈出一個消息了。而且我們所實(shí)例化的對象可以是全局唯一的。

<!-- message.html -->
<!-- 省略... -->
 <script>
// message可以定義為全局對象,項(xiàng)目中可以直接調(diào)用。
const message = new Message();
message.show({
 type: 'success',
 text: '點(diǎn)個關(guān)注不迷路~'
});
</script>

所以呢,我們要先寫一個Message類,并且必須要實(shí)現(xiàn)一個show方法。

/* message.js */
 class Message {
 constructor() {
 }
 show({ type = 'info', text = '' }) {
 }
}

這里我直接用了es6的class關(guān)鍵詞,其實(shí)他的內(nèi)部還是原型鏈的形式。用class呢,可以讓我們更直觀的了解這個類。

根據(jù)我們在第一部分的分析,所有的消息元素都是需要在js中創(chuàng)建的,所以我們不需要使用者來寫任何html代碼,那么我們只需要在對象被實(shí)例化new Message()的時候,就去創(chuàng)建消息容器message-container,后續(xù)在調(diào)用show方法時候,直接把消息插入到message-container內(nèi)部即可。

/* message.js */
 class Message {
 /**
 * 構(gòu)造函數(shù)會在實(shí)例化的時候自動執(zhí)行
 */
 constructor() {
 const containerId = 'message-container';
 // 檢測下html中是否已經(jīng)有這個message-container元素
 this.containerEl = document.getElementById(containerId);
 if (!this.containerEl) {
 // 創(chuàng)建一個Element對象,也就是創(chuàng)建一個id為message-container的dom節(jié)點(diǎn)
 this.containerEl = document.createElement('div');
 this.containerEl.id = containerId;
 // 把message-container元素放在html的body末尾
 document.body.appendChild(this.containerEl);
 }
 }
 show({ type = 'info', text = '' }) {
 }
}

這樣,我們調(diào)用const message = new Message()的時候會在dom中自動的插入一個message-container節(jié)點(diǎn)。
那么,最重要的還是我們的show方法:

創(chuàng)建一個消息節(jié)點(diǎn),并把它追加到message-container容器的末尾。
設(shè)定一個時間,在這個時間結(jié)束后自動的將消息移除。
監(jiān)聽“關(guān)閉按鈕”的click事件,來讓用戶可以手動的移除消息。
我們一步一步來。

4.1 創(chuàng)建一個消息節(jié)點(diǎn),并把它追加到message-container容器的末尾。

class Message {
 // 省略...
 show({ type = 'info', text = '' }) {
 // 創(chuàng)建一個Element對象
 let messageEl = document.createElement('div');
 // 設(shè)置消息class,這里加上move-in可以直接看到彈出效果
 messageEl.className = 'message move-in';
 // 消息內(nèi)部html字符串
 messageEl.innerHTML = `
 <span class="icon icon-${type}"></span>
 <div class="text">${text}</div>
 <div class="close icon icon-close"></div>
 `;
 // 追加到message-container末尾
 // this.containerEl屬性是我們在構(gòu)造函數(shù)中創(chuàng)建的message-container容器
 this.containerEl.appendChild(messageEl);
 }

我們來調(diào)用下試試~

<!-- message.html -->
<!-- 省略... -->
 <button class="btn">彈窗消息提醒</button>
 <script>
 // message可以定義為全局對象,項(xiàng)目中可以直接調(diào)用。
 const message = new Message();
 document.querySelector('.btn').addEventListener('click', () => {
 message.show({
 type: 'success',
 text: '點(diǎn)個關(guān)注不迷路~'
 });
 });
 </script>


4.2 設(shè)定一個時間,在這個時間結(jié)束后自動的將消息移除。

// message.js
 class Message {
 // 省略...
 show({ type = 'info', text = '', duration = 2000 }) {
 // 省略...
 // 用setTimeout來做一個定時器
 setTimeout(() => {
 // Element對象內(nèi)部有一個remove方法,調(diào)用之后可以將該元素從dom樹種移除!
 messageEl.remove();
 }, duration);
 }
}

 可以看到,消息在過了2秒后,自動的從dom樹中移除了,不過呢并沒有動畫,還記得前邊我們寫了move-out類嗎?這個類和message是同級的?,F(xiàn)在我們只需要在定時結(jié)束后把這個類應(yīng)用到message元素上就行。

// message.js
 class Message {
 // 省略...
 show({ type = 'info', text = '', duration = 2000 }) {
 // 省略...
 // 用setTimeout來做一個定時器
 setTimeout(() => { // 首先把move-in這個彈出動畫類給移除掉,要不然會有問題,可以自己測試下
 messageEl.className = messageEl.className.replace('move-in', ''); // 增加一個move-out類
 messageEl.className += 'move-out';
 // 這個地方是監(jiān)聽動畫結(jié)束事件,在動畫結(jié)束后把消息從dom樹中移除。
 // 如果你是在增加move-out后直接調(diào)用messageEl.remove,那么你不會看到任何動畫效果
 messageEl.addEventListener('animationend', () => {
 // Element對象內(nèi)部有一個remove方法,調(diào)用之后可以將該元素從dom樹種移除!
 messageEl.remove();
 });
 }, duration);
 }
}

4.3 監(jiān)聽“關(guān)閉按鈕”的click事件,來讓用戶可以手動的移除消息。

有時候呢,我們希望消息能夠一直展示,直到用戶來手動的關(guān)閉掉,那么首先我們要加一個參數(shù),用來控制是否展示這個關(guān)閉按鈕。

// message.js
 class Message {
 // 省略...
 show({ type = 'info', text = '', duration = 2000, closeable = false }) {
 // 創(chuàng)建一個Element對象
 let messageEl = document.createElement('div');
 // 設(shè)置消息class,這里加上move-in可以直接看到彈出效果
 messageEl.className = 'message move-in';
 // 消息內(nèi)部html字符串
 messageEl.innerHTML = `
 <span class="icon icon-${type}"></span>
 <div class="text">${text}</div>
 `;
 // 是否展示關(guān)閉按鈕
 if (closeable) {
 // 創(chuàng)建一個關(guān)閉按鈕
 let closeEl = document.createElement('div');
 closeEl.className = 'close icon icon-close';
 // 把關(guān)閉按鈕追加到message元素末尾
 messageEl.appendChild(closeEl);
 // 監(jiān)聽關(guān)閉按鈕的click事件,觸發(fā)后將調(diào)用我們的close方法
 // 我們把剛才寫的移除消息封裝為一個close方法
 closeEl.addEventListener('click', () => {
 this.close(messageEl)
 });
 }
 // 追加到message-container末尾
 // this.containerEl屬性是我們在構(gòu)造函數(shù)中創(chuàng)建的message-container容器
 this.containerEl.appendChild(messageEl);
 // 只有當(dāng)duration大于0的時候才設(shè)置定時器,這樣我們的消息就會一直顯示
 if (duration > 0) {
 // 用setTimeout來做一個定時器
 setTimeout(() => {
 this.close(messageEl);
 }, duration);
 } 
 }
 /**
 * 關(guān)閉某個消息
 * 由于定時器里邊要移除消息,然后用戶手動關(guān)閉事件也要移除消息,所以我們直接把移除消息提取出來封裝成一個方法
 * @param {Element} messageEl 
 */
 close(messageEl) {
 // 首先把move-in這個彈出動畫類給移除掉,要不然會有問題,可以自己測試下
 messageEl.className = messageEl.className.replace('move-in', '');
 // 增加一個move-out類
 messageEl.className += 'move-out';
 // 這個地方是監(jiān)聽動畫結(jié)束事件,在動畫結(jié)束后把消息從dom樹中移除。
 // 如果你是在增加move-out后直接調(diào)用messageEl.remove,那么你不會看到任何動畫效果
 messageEl.addEventListener('animationend', () => {
 // Element對象內(nèi)部有一個remove方法,調(diào)用之后可以將該元素從dom樹種移除!
 messageEl.remove();
 });
 }
}
我們來調(diào)用下試試~
<!-- message.html -->
<!-- 省略... -->
 <button class="btn">彈窗消息提醒</button>
 <script>
 // message可以定義為全局對象,項(xiàng)目中可以直接調(diào)用。
 const message = new Message();
 document.querySelector('.btn').addEventListener('click', () => {
 message.show({
 type: 'warning',
 text: '點(diǎn)我旁邊的叉叉試試',
 duration: 0, // 不會自動消失
 closeable: true, // 可手動關(guān)閉
 });
 });
 </script>

其實(shí)已經(jīng)寫的差不多了,不過還是有一些小問題,比如當(dāng)我們彈出兩個甚至更多消息的時候,如果前邊的消息消失后,下面的消息會直接跳到上面的位置,很僵硬,沒有任何的滑動。

我們可以通過css的transition屬性來讓meesage的高度逐漸變小,這樣下面的元素就會根據(jù)變化來逐漸上移。

/* message.css */
/* 省略... */
 #message-container .message {
 background: #fff;
 margin: 10px 0;
 padding: 0 10px;
 height: 40px;
 box-shadow: 0 0 10px 0 #ccc;
 font-size: 14px;
 border-radius: 3px;
 /* 讓消息內(nèi)部的三個元素(圖標(biāo)、文本、關(guān)閉按鈕)可以垂直水平居中 */
 display: flex;
 align-items: center;
/* 增加一個過渡屬性,當(dāng)message元素的高度和margin變化時候?qū)幸粋€過渡動畫 */
 transition: height 0.2s ease-in-out, margin 0.2s ease-in-out;
} 
/* 省略... */
然后我們只需要在Message類的close方法中做一下改變:
 close(messageEl) {
 // 首先把move-in這個彈出動畫類給移除掉,要不然會有問題,可以自己測試下
 messageEl.className = messageEl.className.replace('move-in', '');
 // 增加一個move-out類
 messageEl.className += 'move-out';
 // move-out動畫結(jié)束后把元素的高度和邊距都設(shè)置為0
 // 由于我們在css中設(shè)置了transition屬性,所以會有一個過渡動畫
 messageEl.addEventListener('animationend', () => {
 messageEl.setAttribute('style', 'height: 0; margin: 0');
 });
 // 這個地方是監(jiān)聽transition的過渡動畫結(jié)束事件,在動畫結(jié)束后把消息從dom樹中移除。
 messageEl.addEventListener('transitionend', () => {
 // Element對象內(nèi)部有一個remove方法,調(diào)用之后可以將該元素從dom樹種移除!
 messageEl.remove();
 });
 }

結(jié)尾
好了,基本上已經(jīng)寫好了,不過為了各個瀏覽器的兼容性,建議大家用babel轉(zhuǎn)碼,如果想發(fā)布,可以用webpack把js和css一塊打包。
不過我們還是少考慮了一個場景,現(xiàn)在的關(guān)閉消息都是對象內(nèi)部調(diào)用close方法來實(shí)現(xiàn),如果我們希望外部能夠控制消息的關(guān)閉呢,比如我請求服務(wù)器時候彈出一個loading的消息,現(xiàn)在服務(wù)器返回?cái)?shù)據(jù)后,我怎么來關(guān)閉這個消息呢。
很簡單,各位自行實(shí)現(xiàn)吧!

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。

分享文章:如何用原生js寫一個彈窗消息提醒插件
網(wǎng)站鏈接:http://aaarwkj.com/article32/iipesc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供營銷型網(wǎng)站建設(shè)、品牌網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)、用戶體驗(yàn)、Google網(wǎng)站收錄

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

商城網(wǎng)站建設(shè)
中文字幕人妻秘书社长| 免费看夫妻性生活视频| 精品亚洲综合一区二区| 午夜国产精品福利一二| 免费在线观看成人av| 中文字幕四虎在线观看| 色综合色狠狠天天综合色| 日韩精品在线观看天堂| 久草福利视频免费播放| 日韩成人激情在线观看| 亚洲日本一区二区高清在线 | 国产精品日本在线观看| 五十路六十路美熟人妻| 成人黄色av大片在线观看| 传媒视频在线免费观看| 一区二区三区av天堂| 蜜臀久久精品亚洲一区| 黄色日韩大片在线观看| 国产福利午夜一区二区| 亚洲欧美日韩国产亚洲欧美日韩国产 | 中文字幕国产精品综合一区| 日本不卡一区二区在线观看| 欧美一区二区男人天堂| 国产美女主播视频一区二区三区| 亚洲中文字幕av每天更新| 亚洲精品中文字幕乱码三区91| 精品久久一区麻豆香蕉| 中文日本强暴人妻另类视频| 在线欧美亚洲观看天堂| 国产三级国产精品国产专播| 色欧美在线视频观看日韩| va精品人妻一区二区三区| 久久热最新免费观看视频| 四虎在线观看最新入口| 日本不卡二区高清三区| 欧美亚洲国产精品综合在线| 思思久久96热在精品国产| 日本欧美自拍偷拍高清| 成人av影视中文字幕| 精品熟妇人妻一区二区三区| 国产一区二区精品不卡|