目录
闲言
周末花时间写了一个消息提示框,因之前项目里面用到的提示框有好几种,没有统一起来,这次就抽时间搞一个。
大概试了一下感觉还不错,蛮好用的,就拿出来分享,目前还没有用到项目中,可能会有些不适合的场景到时候就再修正吧。
效果图:
图1
图2:
图3:
图4:
语法
textToast(msg,option);
参数说明:
msg:需要展示的内容。
option:可选对象,包含以下属性:
title --展示的标题
type --show表示一直显示,其他为短暂显示后隐藏
isbg --是否有遮罩 true表示有,默认没有
msgType -- 消息类型 suc表示成功会显示一个笑脸,fail显示一个哭脸 warn显示一个警告图片,默认不显示
msgColor --消息内容的字体颜色,缺省默认白色
color --消息内容展示区域的背景颜色,默认黑色
duration --消息窗口持续时间,缺省默认3000毫秒,可以设置毫秒数、fast、normal、slow等,如果type='show'的话此字段不生效
width --消息窗口宽度 可以填400或者400px,缺省300px
openCallback --消息窗口打开的回调函数
closeCallback --消息窗口关闭的回调函数
faded -- 渐入渐出 true/false 缺省为true
代码中会给出几个例子供参考,自己也可以灵活配置:
- 有标题、有遮罩、有笑脸、一直展示、宽度设置400、默认渐入渐出,需要点击关闭。
- 自动关闭、背景颜色设置green、无遮罩、设置哭脸、默认渐入渐出、宽度设置错类型则默认300px等。
- 自动关闭、有遮罩、显示警告,默认渐入渐出。
- 有消息内容,默认自动关闭、不执行渐入渐出。
- 有消息内容,默认自动关闭、默认渐入渐出。
- 有消息内容,默认自动关闭、默认渐入渐出,并且有打开、关闭回调函数。
- 有消息内容,默认自动关闭、不执行渐入渐出,并且有打开、关闭回调函数。
完整代码
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
</head>
<body>
<button onclick="toast()">toast</button>
<button onclick="toast1()">toast1</button>
<button onclick="toast2()">toast2</button>
<button onclick="toast3()">toast3</button>
<button onclick="toast4()">toast4</button>
<button onclick="toast5()">toast5</button>
<button onclick="toast6()">toast6</button>
</body>
<script>
function animation(){
return {
show:show,
hide:hide,
fadeToggle:fadeToggle,
fadeIn:fadeIn,
fadeOut:fadeOut,
fadeTo:fadeTo,
fadeToggle:fadeToggle,
getStyle:getStyle
}
//获取属性值
function getStyle(obj, prop) {
var prevComputedStyle = document.defaultView ? document.defaultView.getComputedStyle( obj, null ) : obj.currentStyle;
return prevComputedStyle[prop];
}
/*
obj:dom对象
speed:执行速度 fast slow 3000等
func:回调函数
*/
function hide(obj,speed,func){
if(obj.style.display==='none'){
return ;
}
//获取本来的宽带和高度
var width = getStyle(obj, 'width');
var height = getStyle(obj, 'height');
var new_func = function(){
//设置回原来的高度和宽度
obj.style['width'] = width;
obj.style['height'] = height ;
func();
}
animate(obj,{opacity: 0,display:'none',width:0,height:0},speed,new_func);
}
function show(obj,speed,func){
if(obj.style.display!=='none'){
return ;
}
//获取本来的宽带和高度
var width = getStyle(obj, 'width');
var height = getStyle(obj, 'height');
//设置从0开始
obj.style['width'] = 0;
obj.style['height'] = 0 ;
animate(obj,{opacity: 1,display:'block',width:width,height:height},speed,func);
}
function toggle(obj,speed,func){
if(obj.style.display==='none'){
show(obj,speed,func);
}else{
hide(obj,speed,func);
}
}
function fadeOut(obj,speed,func){
animate(obj,{opacity: 0,display:'none'},speed,func);
}
function fadeIn(obj,speed,func){
animate(obj,{opacity: 1,display:'block'},speed,func);
}
function fadeToggle(obj,speed,func){
if(obj.style.display==='none'){
fadeIn(obj,speed,func);
}else{
fadeOut(obj,speed,func);
}
}
function fadeTo(obj,speed,opacity,func){
if(opacity>0 && obj.style.display==='none'){
animate(obj,{opacity: opacity,display:'block'},speed,func);
}else{
animate(obj,{opacity: opacity},speed,func);
}
}
/*
obj:dom对象
prop:动画参数
speed:执行速度 fast slow 3000等
func:回调函数
*/
function animate(obj,prop,speed,func){
//防止重复动画事件
if(obj.timer) return ;
//定义定时器执行次数和总执行时间
var limit=20,totalTime;
if(typeof speed==='number'){//如果传入的是
totalTime = speed;
}else if(speed==='slow'){
totalTime = 600;
}else if(speed==='fast'){
totalTime = 200;
}else{
totalTime = 400;
}
var time = totalTime/limit;
var n=0,cache={},display,primary_cur;//cache用来缓存,省的每次都去dom获取
obj.timer = setInterval(function(){
n++;//执行次数每次递增
for(var p in prop){
if("display"===p) {
display = prop["display"];
if(display!=='none'){
obj.style['display'] = display;
}
delete prop["display"];
continue;
}
//判断是否是可以递增的属性,如果不是则直接让它生效,并从prop中删除,删除后就不用每次任务都执行它
var reg = /^(\d)+(px$)?/;//数字和像素这样的判定为可以递增的属性
if(!reg.test(prop[p])){
obj.style[p] = prop[p];
delete prop[p];
continue;
}
var value,opacityFlag=(p == "opacity")?true:false;
var cur = 0;
if(cache[p+"_cur"]){//从缓存中取
cur = cache[p+"_cur"];
value = cache[p+"_value"];
}else{
value = prop[p];
if(opacityFlag) {
//如果本来是隐藏的则cur默认就是0
if(getStyle(obj, 'display')!=='none'){
cur = Math.round(parseFloat(getStyle(obj, p)) * 100);
}
} else {
cur = parseInt(getStyle(obj, p));
//处理100px的格式
(typeof value==='string') && (value=value.replace(/px$/,""));
}
primary_cur=cur;
cache[p+"_value"] = value;
}
var incre ;
if(cache[p+'_increment']){//如果缓存中有则从中取
incre = cache[p+'_increment'];
}else{
if(opacityFlag){
incre = (value*100-cur)/limit;//计算每次变化值
}else{
incre = (value-cur)/limit;//计算每次变化值
}
cache[p+'_increment']= incre;
}
//缓存起来,这样就不用每次都去dom中获取了。
cache[p+"_cur"] = cur + incre;
if (opacityFlag) {
obj.style.filter = "alpha(opacity:"+(cur + incre)+" )";
obj.style.opacity = (cur + incre)/100 ;
}else {
obj.style[p] = cur + incre + "px";
}
}
//如果达到了最大执行次数,要清除定时器,并执行回调函数
if(n==limit){
if(display==='none'){
obj.style['display'] = 'none';
}
//清除定时器
clearInterval(obj.timer);
obj.timer=undefined;
func && func();
}
},time)
}
}
var _ = {
isFunction : function(o){
return o!== null &&typeof o ==='function';
}
}
function textToast(msg,option){
var animate = animation();
var option = option||{},duration=3000,color='#6a6a6a',msgColor='white',type,msgType='normal',openCallback,closeCallback,showFlag
,bgFlag,width='300',left,title,faded=true;
if(option){
option.duration && (function(){
duration = option.duration;
if(duration==='slow'){
duration = '3000';
}else if(duration==='fast'){
duration = '1000';
}else if(duration==='normal'){
duration = '2000';
}
}());
option.openCallback && (openCallback = option.openCallback );
option.closeCallback && (closeCallback = option.closeCallback );
option.color && (color = option.color );
option.msgColor && (msgColor = option.msgColor );
option.type && (type = option.type);
option.msgType && (msgType = option.msgType);
option.title && (title = option.title);
if(typeof option.isbg==='boolean'){
bgFlag = option.isbg;
}
if(typeof option.faded==='boolean'){
faded = option.faded;
}
(type==='show')?(showFlag=true):(showFlag=false);//是否一直显示
if(type==='show'){//如果是一直展示的,必须要有关闭按钮和标题
//判断有没有标题信息,没有就默认
if(!title){
title='消息';
}
}
if(option.width){
var t_width = option.width;
if(/(\d+)px/.test(t_width) || /(\d+)/.test(t_width)){
width = RegExp.$1;
}
}
left = (window.screen.availWidth-30-width)/2+'px';
width+='px';
}
var toastDiv = document.getElementById("toast_content_div");
if(toastDiv){
if(showFlag===toastDiv.alwaysShowFlag && bgFlag===toastDiv.bgFlag){//toastDiv div已经创建,并且显示状态没有改变,则不需要重新生成DIV
if(bgFlag){//如果是有遮罩的,相互切换需要另外处理
/*var toast_content_bg = document.getElementById("toast_content_bg");
toast_content_bg.style.height = getToastHeight()+"px";
var toast_content_child_div = document.getElementById("toast_content_child_div");
toast_content_child_div.style.width=width;
toast_content_bg.childNodes[0].style.top = (window.scrollY||window.document.documentElement.scrollTop) + window.screen.availHeight * 0.25 +'px';
*/
toastDiv.parentElement.removeChild(toastDiv);
clearTimeout(toastDiv.timmer);
toastDiv=null;
}else{
var toast_span_msg_id = document.getElementById("toast_span_msg_id");
toast_span_msg_id.innerText=msg;
toast_span_msg_id.style.color=msgColor;
toastDiv.style.backgroundColor=color;
toastDiv.style.top = (window.scrollY||window.document.documentElement.scrollTop) + window.screen.availHeight * 0.25 +'px';
//用渐入来显示
showHide('show');
clearTimeout(toastDiv.timmer);
//执行显示函数
openCallback && _.isFunction(openCallback) && openCallback();
if(!showFlag){
toastDiv.timmer = setTimeout(function(){
showHide('hide',closeCallback);
},duration);
}
return ;
}
}else{
toastDiv.parentElement.removeChild(toastDiv);
clearTimeout(toastDiv.timmer);
toastDiv=null;
}
}
var html='';
toastDiv = document.createElement("div");
toastDiv.alwaysShowFlag=showFlag;
toastDiv.bgFlag=bgFlag;
toastDiv.id="toast_content_div";
toastDiv.style.position = "absolute";
if(bgFlag){
toastDiv.style.top="0px";
toastDiv.style.margin ="0";
toastDiv.style.padding ="0";
html = '<div id="toast_content_bg" style="DISPLAY: block; Z-INDEX: 1; BACKGROUND: #ccc;LEFT: 0px; POSITION: absolute; TOP: 0px;FILTER: alpha(opacity=80);opacity: 0.8">';
html +='<div id="toast_content_child_div" style="background:'+color+';width:'+width+';z-index:5;left:'+left+';top:25%;position:absolute;border-radius:8px;FILTER: alpha(opacity=0);opacity: 0">';
}else{
toastDiv.style.cssText="background:"+color+";width:"+width+";z-index:5;left:"+left+";top:35%;position:absolute;border-radius:8px;FILTER: alpha(opacity=70);opacity: 0.7;display:none;min-height:80px;";
}
if(title){
html +='<div style="border-bottom: 1px dashed rgb(221, 221, 221);">';
html +='<div><span style="display: block;font-size: 14px;padding: 8px 15px;background-color: lightgoldenrodyellow;border-radius: 8px 8px 0px 0px;border-bottom: 2px solid rgb(48, 153, 220);font-weight: bold;">' + title + '</span>';
html +='<span id="msg_ico" style="display: block;position: absolute;right: 10px;top: 9px;border: 1px solid gray;width: 18px;height: 18px;text-align: center;line-height: 15px;cursor: pointer;border-radius: 12px;">x</span></div>';
}
html +='<div style="margin-left: 10px;margin-right: 10px;">';
if(msgType==='suc'||msgType==='success'){
html +='<span style="font-size: 40px;color: springgreen;">☺</span>';
}else if(msgType==='fail'){
html +='<span style="font-size: 40px;color: orangered;">☹</span>';
}else if(msgType==='warn'){
html +='<span style="font-size: 40px;color: yellow;">⚠</span>';
}else{//没有图片
}
html += "<span id='toast_span_msg_id' style='font-size:16px;padding-left:5px;z-index:6;text-align: center;color:"+msgColor+";word-wrap:break-word;line-height:2;'>"+msg+"</span>";
html +='</div></div>';
function closeEvent(){
return closeDiv.bind(this);
}
if(showFlag){
html +="<div style='margin:3px;text-align: center;'>"
+"<input id='confirmEventDiv' type='button' value='确定' style='width:85px;height:30px;color:white;border:none;cursor:pointer;background-color:rgb(187, 28, 28);letter-spacing: 6px;'>"
+"<input id='closeEventDiv' type='button' value='取消' style='width:85px;height:30px;color:white;border:none;cursor:pointer;background-color:slategray;margin-left: 20px;letter-spacing: 6px;'>"
}
if(bgFlag){
html +="</div></div>";
}
toastDiv.innerHTML = html ;
window.document.body.appendChild(toastDiv);
if(bgFlag){
var toast_content_bg = document.getElementById("toast_content_bg");
toast_content_bg.style.width =document.body.clientWidth-10+"px";
toast_content_bg.style.height=getToastHeight()+'px';
toast_content_bg.childNodes[0].style.top = (window.scrollY||window.document.documentElement.scrollTop) + window.screen.availHeight * 0.25 +'px';
}else{
toastDiv.style.top = (window.scrollY||window.document.documentElement.scrollTop) + window.screen.availHeight * 0.25 +'px';
}
//执行显示
showHide('show',openCallback);
if(showFlag){
var confirmEventDiv = document.getElementById("confirmEventDiv");
var closeEventDiv = document.getElementById("closeEventDiv");
var msg_ico = document.getElementById("msg_ico");
if(document.addEventListener){
confirmEventDiv && confirmEventDiv.addEventListener('click',confirmDiv);
closeEventDiv && closeEventDiv.addEventListener('click',closeDiv);
msg_ico && msg_ico.addEventListener('click',closeDiv);
}else{
confirmEventDiv && confirmEventDiv.attachEvent('onclick',confirmDiv);
closeEventDiv && closeEventDiv.attachEvent('onclick',closeDiv);
msg_ico && msg_ico.attachEvent('onclick',closeDiv);
}
}
if(!showFlag){
toastDiv.timmer = setTimeout(function(){
showHide('hide',closeCallback);
},duration);
}
function getToastHeight(){
return window.screen.availHeight > document.body.clientHeight ? window.screen.availHeight : document.body.clientHeight;
}
function confirmDiv(){//关闭是不执行回调函数的
clearTimeout(toastDiv.timmer);
showHide('hide',closeCallback);
}
function closeDiv(){//关闭是不执行回调函数的
clearTimeout(toastDiv.timmer);
showHide('hide');
}
function showHide(type,callback){
if(bgFlag){
var toast_content_bg_div = document.getElementById("toast_content_div");
var toast_content_child_div = document.getElementById("toast_content_child_div");
if(faded){//需要执行渐入渐出动画
if(type==='hide'){
toast_content_bg_div && (animate.fadeOut(toast_content_bg_div,'slow'));
toast_content_child_div && (animate.fadeOut(toast_content_child_div,'slow'));
}else{
toast_content_bg_div && (animate.fadeIn(toast_content_bg_div,'slow'));
toast_content_child_div && (animate.fadeIn(toast_content_child_div,'slow'));
}
}else{
do_showHide(toast_content_bg_div,type,true);
do_showHide(toast_content_child_div,type,true);
}
}else{
if(faded){//需要执行渐入渐出动画
if(type==='hide'){
toastDiv && (animate.fadeOut(toastDiv,'slow'));
}else{
toastDiv && (animate.fadeIn(toastDiv,'slow'));
}
}else{
do_showHide(toastDiv,type);
}
}
setTimeout(function(){
callback && _.isFunction(callback) && callback();
},0)
function do_showHide(el,type,opac){
if(type==='hide'){
el && (el.style.display='none');
}else{
if(el){
if(opac){
el.style.filter='alpha(opacity:100)';
el.style.opacity=1;
}
el.style.display='block';
}
}
}
}
}
/*语法
textToast(msg,option);
参数说明:
msg:需要展示的消息内容
option可选对象,包含以下属性:
title --展示的标题
type --show表示一直显示,其他为短暂显示后隐藏
isbg --是否有遮罩 true表示有,默认没有
msgType -- 消息类型 suc表示成功会显示一个笑脸,fail显示一个哭脸 warn显示一个警告图片,默认不显示
msgColor --消息内容的字体颜色,缺省默认白色
color --消息内容展示区域的背景颜色,默认黑色
duration --消息窗口持续时间,缺省默认3000毫秒,可以设置毫秒数、fast、normal、slow等,如果type='show'的话此字段不生效
width --消息窗口宽度 可以填400或者400px,缺省300px
openCallback --消息窗口打开的回调函数
closeCallback --消息窗口关闭的回调函数
faded -- 渐入渐出 true/false 缺省为true
*/
function toast(){
textToast('有标题、有遮罩、有笑脸、一直展示、宽度设置400、默认渐入渐出,需要点击关闭',{title:'消息',type:'show',isbg:true,msgType:'suc',width:400} );
}
function toast1(){
var option={
duration:'slow',color:'green',msgType:'fail',width:'sdf'
}
textToast('自动关闭、背景颜色设置green、无遮罩、设置哭脸、默认渐入渐出、宽度设置错类型则默认300px等',option);
}
function toast2(){
var option={
duration:'slow',isbg:true,msgType:'warn'
}
textToast('自动关闭、有遮罩、显示警告,默认渐入渐出',option);
}
function toast3(){
textToast('有消息内容,默认自动关闭、不执行渐入渐出',{faded:false,isbg:true,type:'show'});
}
function toast4(){
textToast('有消息内容,默认自动关闭、默认渐入渐出');
}
function toast5(){
textToast('有消息内容,默认自动关闭、默认渐入渐出,并且有打开、关闭回调函数',{
openCallback:function(){
alert('openCallback')
},
closeCallback:function(){
alert('closeCallback')
}
});
}
function toast6(){
textToast('有消息内容,默认自动关闭、不执行渐入渐出,并且有打开、关闭回调函数',{faded:false,isbg:true,type:'show',
openCallback:function(){
alert('openCallback')
},
closeCallback:function(){
alert('closeCallback')
}});
}
</script>
</html>
最后,图片的话目前是固定的笑脸、哭脸、警告3种,如果自己想要自定义的话可以自己稍作修改,也很好改,option加入一个图片路径参数,找到展示图片的地方再处理一下既可!