如何用原生js写一个弹窗消息提醒插件(3)

// 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'; // 这个地方是监听动画结束事件,在动画结束后把消息从dom树中移除。 // 如果你是在增加move-out后直接调用messageEl.remove,那么你不会看到任何动画效果 messageEl.addEventListener('animationend', () => { // Element对象内部有一个remove方法,调用之后可以将该元素从dom树种移除! messageEl.remove(); }); }, duration); } }

4.3 监听“关闭按钮”的click事件,来让用户可以手动的移除消息。

有时候呢,我们希望消息能够一直展示,直到用户来手动的关闭掉,那么首先我们要加一个参数,用来控制是否展示这个关闭按钮。

// message.js class Message { // 省略... show({ type = 'info', text = '', duration = 2000, closeable = false }) { // 创建一个Element对象 let messageEl = document.createElement('div'); // 设置消息class,这里加上move-in可以直接看到弹出效果 messageEl.className = 'message move-in'; // 消息内部html字符串 messageEl.innerHTML = ` <span></span> <div>${text}</div> `; // 是否展示关闭按钮 if (closeable) { // 创建一个关闭按钮 let closeEl = document.createElement('div'); closeEl.className = 'close icon icon-close'; // 把关闭按钮追加到message元素末尾 messageEl.appendChild(closeEl); // 监听关闭按钮的click事件,触发后将调用我们的close方法 // 我们把刚才写的移除消息封装为一个close方法 closeEl.addEventListener('click', () => { this.close(messageEl) }); } // 追加到message-container末尾 // this.containerEl属性是我们在构造函数中创建的message-container容器 this.containerEl.appendChild(messageEl); // 只有当duration大于0的时候才设置定时器,这样我们的消息就会一直显示 if (duration > 0) { // 用setTimeout来做一个定时器 setTimeout(() => { this.close(messageEl); }, duration); } } /** * 关闭某个消息 * 由于定时器里边要移除消息,然后用户手动关闭事件也要移除消息,所以我们直接把移除消息提取出来封装成一个方法 * @param {Element} messageEl */ close(messageEl) { // 首先把move-in这个弹出动画类给移除掉,要不然会有问题,可以自己测试下 messageEl.className = messageEl.className.replace('move-in', ''); // 增加一个move-out类 messageEl.className += 'move-out'; // 这个地方是监听动画结束事件,在动画结束后把消息从dom树中移除。 // 如果你是在增加move-out后直接调用messageEl.remove,那么你不会看到任何动画效果 messageEl.addEventListener('animationend', () => { // Element对象内部有一个remove方法,调用之后可以将该元素从dom树种移除! messageEl.remove(); }); } } 我们来调用下试试~

<!-- message.html --> <!-- 省略... --> <button>弹窗消息提醒</button> <script> // message可以定义为全局对象,项目中可以直接调用。 const message = new Message(); document.querySelector('.btn').addEventListener('click', () => { message.show({ type: 'warning', text: '点我旁边的叉叉试试', duration: 0, // 不会自动消失 closeable: true, // 可手动关闭 }); }); </script>

其实已经写的差不多了,不过还是有一些小问题,比如当我们弹出两个甚至更多消息的时候,如果前边的消息消失后,下面的消息会直接跳到上面的位置,很僵硬,没有任何的滑动。

我们可以通过css的transition属性来让meesage的高度逐渐变小,这样下面的元素就会根据变化来逐渐上移。

/* 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; /* 让消息内部的三个元素(图标、文本、关闭按钮)可以垂直水平居中 */ display: flex; align-items: center; /* 增加一个过渡属性,当message元素的高度和margin变化时候将会有一个过渡动画 */ 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动画结束后把元素的高度和边距都设置为0 // 由于我们在css中设置了transition属性,所以会有一个过渡动画 messageEl.addEventListener('animationend', () => { messageEl.setAttribute('style', 'height: 0; margin: 0'); }); // 这个地方是监听transition的过渡动画结束事件,在动画结束后把消息从dom树中移除。 messageEl.addEventListener('transitionend', () => { // Element对象内部有一个remove方法,调用之后可以将该元素从dom树种移除! messageEl.remove(); }); }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/e5eb2a37bb0517d5c10894e84a561207.html