微信小程序canvas层级过高,遮住弹窗解决方法

页面canvas图层遮住弹出框,导致弹出框无法点击且样式存在问题
在这里插入图片描述

因为canvas组件是由客户端创建的原生组件,原生组件层级是最高的,所以页面中的其他组件无论设置 z-index
为多少都无法盖在原生组件上。
想试着用cover-view组件,能覆盖canvas,map,video,camera等原生组件。但是也有一定的限制。比如:cover-view中只支持嵌套cover-view、cover-image,button。不可以使用input组件,这与我的需求不相符合,所以只能另辟蹊径。

解决方法一:

如果不需要输入,弹窗只需展示文字或者图片,可以使用cover-view组件

解决方法二:

需要input框输入或者选择按钮的,可以使用wx.createCanvasContext通过canvas-id创建canvas绘图对象,在绘制完画布之后生成图片,在data里定义了一个imgSrc,生成图片此时给imgSrc赋值,然后wxml中判断,是否这个值是否有效,若有效,canvas隐藏;否则,显示canvas。

 <!-- canvas展示图代码 -->
<view class="container" style='width:{{width}}px;min-width:100%;'>
   <canvas style='width:{{width}}px;height:300px' canvas-id="columnCanvas" disable-scroll="true" hidden='{{imgSrc}}'></canvas><!-- 用hidden而不用wx:if,原因是点击取消或者关闭弹窗时清空imgSrc的值时canvas无法显示图片直接空白,可能需要重新调用生成canvas图片的方法渲染,因数据比较大就直接用hidden -->
   <image hidden='{{!imgSrc}}' src="{{imgSrc}}" style="width:{{width}}px;height:300px" />
</view>
 <!-- 弹窗代码 -->
<view class='modal-mask' bindtap="hideSetModal" wx:if="{{setModal}}"></view>
<view class='inviterMask bc_fff' wx:if="{{setModal}}" style='top:40%'>
    <view class='fs16 p-t16 b'>
        <text>备注</text>
    </view>
    <input type='text' name='beizhu' placeholder='备注' value='{{beizhu}}' bindinput='getBeizhu' class='t-a_l w90P fs15 h40 l-h40 b1_100' cursor-spacing='60' style='margin-left:5%'></input>
    <view class='fv w100P b-t_1e m-t20'>
        <view class='c_999 fs15 t-a_c h40 w50P b-r_1e l-h40' bindtap='hideSetModal'>取消</view>
        <view class='c_2FC fs15 t-a_c h40 w50P l-h40' bindtap='setInfo'>确定</view>
    </view>
</view>
.container {
   height: 100%;
   display: flex;
   flex-direction: column;
   box-sizing: border-box;
   -webkit-text-size-adjust: none;
   -webkit-user-select: none;
   font-size: 35rpx;
   color: #333;
   font-family: Helvetica, Arial, "Helvetica Neue", "Droid Sans", "Microsoft YaHei", sans-serif;
}
.js_c{
   justify-content: center;
}
//弹窗样式
.modal-mask {
   width: 100%;
   height: 100%;
   position: absolute;
   top: 0;
   left: 0;
   z-index: 1000;
   background: #000;
   opacity: 0.5;
   overflow: hidden;
}

.inviterMask{
  position:absolute;
   top:40%;
   z-index:999999;
   background:#fff;
   width:80%;
   left:10%;
   text-align:center;
   border-radius:5px;
}
Page({
    data: {
       imgSrc:'',//图片
        setModal: false,//弹窗是否显示
        beizhu: '',//输入的备注内容
    },

    onLoad(opt) {
        _this = this
        _data = this.data
    },
    onHide() {
    },
    editName() {
    	_this.canvasToTempImage()//点击编辑按钮显示弹窗并且调用生成图片方法显示图片隐藏canvas
        _this.setData({
            setModal: true//弹窗显示
        });
    },
    hideSetModal() {
        _this.setData({
           setModal: false,//弹窗关闭
           imgSrc:''//点击取消或者关闭弹窗时将imsSrc清空显示canvas
        });
    },
    getBeizhu(e) {
        _this.setData({
            beizhu: e.detail.value
        })
    },
    //设置备注
    setInfo() {
        _this.setData({
           setModal: false,//弹窗关闭
           imgSrc:''//点击确定时将imsSrc清空显示canvas
       })
    },
    //生成图片
   canvasToTempImage: function () {
      wx.canvasToTempFilePath({
         canvasId: "columnCanvas",
         success: (res) => {
            let tempFilePath = res.tempFilePath;
            this.setData({
               imgSrc: tempFilePath,
            });
         }
      }, this);
   }
})

解决方法三:
input用来输入内容,在真机上input组件嵌在<cover-view />内虽然会被忽略,但是点击依旧可以获取焦点;
用一个cover-view显示输入的内容,显示内容的cover-view覆盖在input标签上,使视觉上做到cover-input效果;
控制input的焦点可以在真机上做到cover-input效果,在input失去焦点后赋值给显示内容的cover-view

Page({
    data: {
        latitude: 23.099994,
        longitude: 113.324520,
        inputFocus: false, // input 框的focus状态
        inputModel: '', // input 框的输入内容
        inputInfo: '输入', // cover-view 显示的 input 的输入内容,初始值充当placeholder作用
    },

    onReady: function(e) {
        this.mapCtx = wx.createMapContext('myMap');
    },

    /**
     * 将焦点给到 input(在真机上不能获取input焦点)
     */
    tapInput() {
        this.setData({
            //在真机上将焦点给input
            inputFocus:true,
            //初始占位清空
            inputInfo: ''
        });
    },

    /**
     * input 失去焦点后将 input 的输入内容给到cover-view
     */
    blurInput(e) {
        this.setData({
            inputInfo: e.detail.value || '输入'
        });
    }
})

<view class="page-body">
    <view class="page-section">
        <map id="myMap" style="width: 100%; height: 500px;" latitude="{{latitude}}" scale="18" longitude="{{longitude}}" show-location>
            <cover-image class="center-point" src="/image/location-red.png"></cover-image>
            <!-- cover-input伪代码实现 -->
            <cover-view class='cover-input' bindtap='tapInput'>
                <cover-view class='text'>{{inputInfo}}</cover-view>
                <input class='input' value='{{inputModel}}' focus='{{inputFocus}}' bindblur='blurInput'></input>
            </cover-view>
            <!-- cover-input伪代码实现 -->
        </map>
    </view>
</view>
.page-section{
  box-sizing: border-box;
  padding: 0 30rpx;
}

.center-point {
    height: 30px;
    width: 30px;
    position: relative;
    top: calc(50% - 15px);
    left: 50%;
    transform: translate(-50%, -50%);
}

.cover-input{
  width: 80%;
  height: 32px;
  line-height: 32px;
  border-radius: 5px;
  background-color: rgba(255, 255, 255, 0.9);
  position: relative;
  left: 50%;
  transform: translateX(-50%);
  padding-left: 15rpx;
  padding-right: 15rpx;
}
.text{
  height: 32px;
  line-height: 32px;
}
.input{
  height: 32px;
  line-height: 32px;
  /* margin-top为text的高度,保持视觉上一致 */
  margin-top: -32px; 
}

注:若最外层用了fixed属性,安卓是边输边显示内容,但是苹果必须是失焦才能出现输入的内容,可换成其他的定位方式

  • 9
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值