您现在的位置是:网站首页> 编程资料编程资料

自己写一个uniapp全局弹窗(APP端)_javascript技巧_

2023-05-24 394人已围观

简介 自己写一个uniapp全局弹窗(APP端)_javascript技巧_

效果图: 

 uniapp自带的提示框不符合我们的要求,需要自己写一个提示框,且全局通用。

解决思路:

使用 plus.nativeObj 来绘制窗口以及事件监听。    官方文档

方法如下:

1. 首先创建一个整个屏幕的控件,作为一个父容器。

此时还看不到任何东西

let screenHeight = uni.getSystemInfoSync().screenHeight; let style = { width:'100%', height: (screenHeight + 'px'), left:'0px', top:'0px' }; // 创建原生控件对象 // 参数1: id // 参数2: 控件的样式 let view = new plus.nativeObj.View('showModalView',style);

2. 绘制遮罩层

view.draw([ {tag:'rect',id:'modal',color:`rgba(0,0,0,0.4)`,position:{top:'0px',left:'0px',width:'100%',height:'100%'}} ]); { tag:'rect', // 绘制矩形 id:'modal', // 控件id color:`rgba(0,0,0,0.4)`, // 背景色 position:{top:'0px',left:'0px',width:'100%',height:'100%'} // 位置和大小样式 }

view.draw(tags); 在控件上绘制,传入绘制对象。

绘制对象文档 可绘制图片、矩形区域、文本等内容。  

3.绘制通知框样式

view.draw([ {tag:'rect',id:'modal',color:`rgba(0,0,0,0.4)`,position:{top:'0px',left:'0px',width:'100%',height:'100%'}}, {tag:'rect',id:'content',rectStyles:{borderWidth:'2px',radius:'8px',color:`rgba(36,34,56,1)`},position:{top:startTop+'px',left:startLeft+'px',width:width+'px',height:height+'px'}}, ]); { tag:'rect', id:'content', // 矩形的样式 rectStyles:{borderWidth:'2px',radius:'8px',color:`rgba(36,34,56,1)`}, // 位置和大小. 下面的变量是根据屏幕宽高手动计算的 position:{top:startTop+'px',left:startLeft+'px',width:width+'px',height:height+'px'} } interface RectStyles { attribute String color; attribute String radius; attribute String borderColor; attribute String borderWidth; } 

4. 绘制标题和内容

view.draw([ {tag:'rect',id:'modal',color:`rgba(0,0,0,0.4)`,position:{top:'0px',left:'0px',width:'100%',height:'100%'}}, {tag:'rect',id:'content',rectStyles:{borderWidth:'2px',radius:'8px',color:`rgba(36,34,56,1)`},position:{top:startTop+'px',left:startLeft+'px',width:width+'px',height:height+'px'}}, {tag:'font',id:'title',text:modelInfo.tit,textStyles:{size:'16px',color:'#fff'},position:{top:titleTop+'px',left:startLeft+'px',width:width+'px',height:titleHeight+'px'}}, {tag:'font',id:'text',text:modelInfo.content,textStyles:{size:'14px',color:'#fff',whiteSpace:'normal',align:modelInfo.align},position:{top:contentTop+'px',left:startLeft+'px',width:width+'px',height:contentHeight+'px'}}, // 这个是内容和底部按钮的分割线 {tag:'rect',id:'line',color:'rgba(255,255,255,0.3)',position:{top:lineTop+'px',left:startLeft+'px',width:width+'px',height:'0.5px'}}, ]); { tag:'font', // 绘制文字 id:'title', text:modelInfo.tit, // 文字内容 textStyles:{size:'16px',color:'#fff'}, position:{top:titleTop+'px',left:startLeft+'px',width:width+'px',height:titleHeight+'px'} },

5. 创建确认按钮控件

我们需要给确认按钮设置点击事件,所以它要作为一个新的控件,而不是再刚刚的控件上继续绘制。

// 确认 let viewconfirm=new plus.nativeObj.View('confirm', { width:modelInfo.delCancel?width+'px':'40%', height:buttonHeight+'px', top:lineTop+'px', left:modelInfo.delCancel?startLeft+'px':halfWidthForGlobal +'px', backgroundColor:'rgba(255,255,255,0)', }, ); viewconfirm.draw([ {tag:'font',id:'confirm',text:modelInfo.confirmVal,textStyles:{color:modelInfo.confirmColor,size:'14px'}}, ]);

设置点击事件

viewconfirm.addEventListener("click",(e)=>{ // 发送事件 this.$event({res:true,types:'confirm'}); // 隐藏当前控件(关闭) this.hide(); },false);

将 viewconfirm和view显示出来:

function show(){ this.view.show(); this.confirmModel.show(); }

下面就是将这些挂载到Uni上就可以了。

下面是项目中的完整代码:

index.js 用于绘制

// show_modal/index.js export class show_model{ constructor(option={}) { this.bodyModel=null; this.cancelModel=null; this.confirmModel=null; this.pageHeight=uni.getSystemInfoSync().screenHeight; this.pageWidth = uni.getSystemInfoSync().screenWidth; let opacity = option.opacity || 0.4; let model_tit=option.title||'温馨提示'; let model_content=option.content||"内容" let clickEvent=option.IsclickEvent||false; let cancelVal=option.cancelVal||'取消'; let confirmVal=option.confirmVal||'确认'; let cancelColor=option.cancelColor||'#fff'; // 取消 let confirmColor=option.confirmColor||'#fff'; // 确认 let delCancel=option.delCancel||false; let align=option.align||"center"; let fn = ()=>{}; this.$event = option.$event || fn; let backOff=option.backOff||false; //#ifdef APP-PLUS this.creatView({height:`${this.pageHeight}px`,top:0},opacity,clickEvent,{'tit':model_tit,'content':model_content,cancelVal,confirmVal,confirmColor,cancelColor,delCancel,align}) if(!backOff){ this.backbtn(); } //#endif } backbtn(){ let that=this; plus.key.addEventListener('backbutton', function (e) { that.hide(); },false) } //生成提示框view creatView(style,opa,clickEvent,modelInfo){ style = { left:'0px', width:'100%', ...style } let platform = plus.os.name.toLowerCase(); let view = new plus.nativeObj.View('showModalView',style); let width = 300; let height = 150; let titleHeight = 20; let contentHeight = 60; let startTop = (this.pageHeight - height) / 2; let startLeft = (this.pageWidth - width) / 2; let titleTop = startTop + 10; let contentTop = titleTop+30; let lineTop = startTop + height - 40; let buttonHeight = 40; let halfWidth = width / 2; let halfWidthForGlobal = startLeft + halfWidth; if(platform == "ios"){ view.draw([ {tag:'rect',id:'modal',color:`rgba(0,0,0,${opa})`,position:{top:'0px',left:'0px',width:'100%',height:'100%'}}, {tag:'rect',id:'content',rectStyles:{borderWidth:'2px',radius:'8px',color:`rgba(36,34,56,1)`},position:{top:startTop+'px',left:startLeft+'px',width:width+'px',height:height+'px'}}, {tag:'font',id:'title',text:modelInfo.tit,textStyles:{size:'16px',color:'#fff'},position:{top:titleTop+'px',left:startLeft+'px',width:width+'px',height:titleHeight+'px'}}, {tag:'font',id:'text',text:modelInfo.content,textStyles:{size:'14px',color:'#fff',whiteSpace:'normal',align:modelInfo.align},position:{top:contentTop+'px',left:startLeft+'px',width:width+'px',height:contentHeight+'px'}}, {tag:'rect',id:'line',color:'rgba(255,255,255,0.3)',position:{top:lineTop+'px',left:startLeft+'px',width:width+'px',height:'0.5px'}}, {tag:'rect',id:'line2',color:'rgba(255,255,255,0.3)',position:{top:lineTop+'px',left:+halfWidthForGlobal+'px',width:modelInfo.delCancel?'0px':'0.5px',height:modelInfo.delCancel?'0px':buttonHeight+'px'}} ]); }else{ view.draw([ {tag:'rect',id:'modal',color:`rgba(0,0,0,${opa})`,position:{top:'0px',left:'0px',width:'100%',height:'100%'}}, {tag:'rect',id:'content',rectStyles:{borderWidth:'2px',radius:'8px',color:`rgba(36,34,56,1)`},position:{top:startTop+'px',left:startLeft+'px',width:width+'px',height:height+'px'}}, {tag:'font',id:'title',text:modelInfo.tit,textStyles:{size:'16px',color:'#fff'},position:{top:titleTop+'px',left:startLeft+'px',width:width+'px',height:titleHeight+'px'}}, {tag:'font',id:'text',text:modelInfo.content,textStyles:{size:'14px',color:'#fff',whiteSpace:'normal',align:modelInfo.align},position:{top:contentTop+'px',left:startLeft+'px',width:width+'px',height:contentHeight+'px'}}, {tag:'rect',id:'line',color:'rgba(255,255,255,0.3)',position:{top:lineTop+'px',left:startLeft+'px',width:width+'px',height:'0.5px'}}, {tag:'rect',id:'line2',color:'rgba(255,255,255,0.3)',position:{top:lineTop+'px',left:halfWidthForGlobal+'px',width:modelInfo.delCancel?'0px':'0.5px',height:modelInfo.delCancel?'0px':buttonHeight+'px'}} ]); } var num = 0.55; if(platform == "ios"){ num = 0.57 } if(!modelInfo.delCancel){ // 取消 let viewCancel=new plus.nativeObj.View('cancel',{width:halfWidth+'px',height:buttonHeight+'px',top:lineTop+'px',left:startLeft+'px',backgroundColor:'rgba(255,255,255,0)'}); viewCancel.draw([ {tag:'font',id:'cancel',text:modelInfo.cancelVal,textStyles:{color:modelInfo.cancelColor,size:'14px'}}, ]); viewCancel.addEventListener("click",(e)=>{ this.$event({res:false,types:'cancel'}); this.hide(); },false); this.cancelModel=viewCancel; } // 确认 let viewconfirm=new plus.nativeObj.View('confirm', { width:modelInfo.delCancel?width+'px':'40%', height:buttonHeight+'px', top:lineTop+'px', left:modelInfo.delCancel?startLeft+'px':halfWidthForGlobal +'px', backgroundColor:'rgba(255,255,255,0)', }, ); viewconfirm.draw([ {tag:'font',id:'confirm',text:modelInfo.confirmVal,textStyles:{color:modelInfo.confirmColor,size:'14px'}}, ]); viewconfirm.addEventListener("click",(e)=>{ this.$event({res:true,types:'confirm'}); this.hide(); },false); //点击蒙布 if(clickEvent){ view.addEventListener("click", (e) => { this.$event({res:false,types:'cover'}); this.hide(); }, false); } this.bodyMode
                
                

-六神源码网