微信小程序中定义好的几种picker选择器,不管是日期选择器还是地区选择器,或是其他的都只有定死的样式和内容。

但是大多数开发程序的情况下还是需要自己写样式的,或是内容的。

例如:

代码如下:

  <view class="free-btns" style="margin-top: 10vh;background:none;">
<button class="free-btn" bindtap="toggleDialog">
选定国家:{{value}}
</button>
</view> <view class="free-dialog {{ showDialog ? 'free-dialog--show' : '' }}">
<view class="free-dialog__mask" bindtap="toggleDialog" />
<view class="free-dialog__container">
<view style="padding: 5% 5% 15%;">
<form bindsubmit='submit' bindreset="reset">
<view bindtap='freetoBack' class="free-button free-dialog-reset">取消</view>
<view bindtap='freeBack' class="free-button free-dialog-submit">确定</view> <radio-group class='free-radios' bindchange="radioChange">
<label class="free-radio" bindtap="click" wx:for="{{items}}" wx:key="{{items}}" data-id="{{index}}" style="{{index==id?'background:#48c23d;color:#fff;':'background:#fff;color:#000;'}}">
<radio value="{{item.name}}" name="{{item.value}}"></radio>
<label class="free-text">{{item.value}}</label>
</label>
</radio-group>
</form> </view>
</view>
</view>

样式:

.free-dialog__mask {
position: fixed;
top:;
left:;
right:;
bottom:;
z-index:;
background: rgba(0, 0, 0, 0.7);
display: none;
}
.free-dialog__container {
position: fixed;
left:;
bottom:;
width: 750rpx;
background: white;
transform: translateY(150%);
transition: all 0.4s ease;
z-index:;
}
.free-dialog--show .free-dialog__container {
transform: translateY(0);
}
.free-dialog--show .free-dialog__mask {
display: block;
}
/*模态框中的内容*/
.free-button{
display: inline-block;
width:50px;
text-align: center;
font-size:20px;
color:#707070;
margin-bottom:20px;
}
.free-dialog-submit{
float: right;
color:#48c23d;
}
radio-group{
margin:10rpx 0rpx;
}
radio-group>label{
width:22.5%;
display: inline-block;
border:1px solid #ddd;
padding:10px 0px;
margin:0px 2px 2px;
} radio-group label radio{
width:100%;
z-index:;
display: none;
}
.checked{
background:#48c23d;
color:#fff;
}
radio-group label .free-text{
width:100%;
text-align: center;
display: inline-block;
}

js:

Page({
data: {
showDialog: false,
items: [
{ name: '中国', value: '中国' },
{ name: '美国', value: '美国' },
{ name: '巴西', value: '巴西' },
{ name: '日本', value: '日本' },
{ name: '英国', value: '英国' },
{ name: '法国', value: '法国' },
{ name: '韩国', value: '韩国' },
{ name: '俄罗斯', value: '俄罗斯' },] },
/*点击变色*/
click:function(e){
var id = e.currentTarget.dataset.id
var that = this
that.setData({
id:id
})
},
onLoad: function (options) {
var that = this
that.setData({
value:'show'
})
},
radioChange: function (e) {
console.log('radio发生change事件,携带value值为:', e.detail.value)
var that = this
that.setData({
value: e.detail.value
})
console.log(this.data.value)
},
toggleDialog() {
this.setData({
showDialog: !this.data.showDialog
});
},
freeBack:function(){
var that = this
if(this.data.value=='show'){
wx.showModal({
title: '提示',
content: '你没有选择任何内容',
})
}
that.setData({
showDialog: !this.data.showDialog
})
},
freetoBack: function () {
var that = this
wx.showModal({
title: '提示',
content: '你没有选择任何内容',
})
that.setData({
showDialog: !this.data.showDialog,
value:'show',
checked: false,
})
},
})

遇到个BUG,就是表单中有textarea组件的时候,弹出层设置z-index,在模拟器上运行没问题,但是真机就无效了,textarea的内容就会穿透出来。

查了资料发现是官方的坑,textarea组件为原生组件层级最高,不能通过 z-index 控制层级。

解决办法:

1、隐藏 textarea:

设置一个值,用wx:if 去控制textarea的显示和隐藏。就是说当弹窗弹出的时候,在textarea做wx:if判断那个值为false,把textarea隐藏,然后关闭弹窗或点击其他的时候,把那个值再设为true,显示textarea。当然hidden原理一样。

代码如下:

<view class='itemArea'>
<view class="form_item">留言类型:</view>
<view class="form_item flex_row jc_between underLine">
<button class="free-btn" bindtap="toggleType">
{{typename}}
</button>
<view class="red" bindtap="toggleType">选择</view>
</view> <view bindtap="hideView">
<view class="free-dialog {{ showType ? 'free-dialog-show' : 'free-dialog_mask' }}">
<view class="free-dialog_mask" bindtap="toggleType" />
<view class="free-dialog_container1">
<view class='p25'>
<form bindsubmit='submit' bindreset="reset">
<radio-group class='free-radios' bindchange="radioChange2">
<label class="free-radio" bindtap="clickType" wx:for="{{msgtype}}" wx:key="{{msgtype}}" data-idn="{{index}}" data-name='{{item.typename}}' data-id='{{item.typeid}}' style="{{index==idn?'background:#FBDBDB;':'background:#F5F5F5;'}}">
<radio value="{{item.typename}}" name="{{item.typename}}"></radio>
<label class="free-text">{{item.typename}}</label>
</label>
</radio-group>
</form>
</view>
</view>
</view> </view>
</view>
<view class='pb20'>
<view class="form_item">留言内容:</view>
<view class="form_item">
<textarea class='form_textarea' hidden="{{noTextarea}}" placeholder='请填写留言内容' bindinput='msgcontent' value="{{msgcontent}}" name="msgcontent"></textarea>
</view>
</view>

js:

data: {
noTextarea: false, //textarea弹出层的时候隐藏
}, //点击其他位置隐藏遮罩层
hideView:function(){
var that = this;
that.setData({
noTextarea: false,
})
}, //选择留言类型
toggleType: function () {
this.setData({
showType: !this.data.showType,
noTextarea: true,
});
},
radioChange2: function (e) {
var that = this;
that.setData({
typename: e.detail.value,
showType: !this.data.showType,
noTextarea: false,
})
console.log(this.data.typename);
},
clickType:function(e){
var that = this;
var idn = e.currentTarget.dataset.idn;
var id = e.currentTarget.dataset.id;
that.setData({
idn: idn,
typeid: id,
noTextarea: false,
})
console.log(that.data.typeid);
},

2、还有一种解决方法是使用替代元素

有时候, textarea穿透的不是遮罩层,或者遮罩层以一种半透明而非完全遮住页面内容的形式呈现,担心用户能够看到因为 textarea的消失而导致页面跳动,产生不好的用户体验,那么就可以使用替代元素来替代 textarea而非将之直接隐藏掉。

基本的 textarea组件只接受文本的输入,抛开可输入性的话,外观上看就是一个含有文本节点的简单元素,只需要获取当前状态下的 textarea中输入的文字,将之赋予给一个样式与 textarea相同的普通元素,就达到了临时替代的效果。

<!-- 这是真正的 textarea组件 -->
<textarea id="text-area" value="{{txtRealContent}}" bindinput='txtInput' wx:if="{{!showMask}}" />
<!-- 这是用于模拟 textarea的替代元素 -->
<view class='rich-text' style="{{('height:' + txtHeight + 'px')}}" wx:else>
<rich-text nodes="{{txtRealContent}}"></rich-text>
</view>
  • 由于需要实时获取 textarea中已经输入的内容,所以给 textarea元素加了个 bindinput的监听器
  • showMask用于标识是否显示遮罩层(或者其他可能会被 textarea穿透的浮动元素),如果显示遮罩层,则隐藏 textarea元素,并显示替代原宿
  • 这里 textarea的隐藏使用了 wx:if,会使其彻底地从页面中消失,而重新显示出来的时候,textarea元素会重新创建,丢失原先输入,所以给其加了个 value属性,其值 txtRealContent就是缓存的 textarea已经输入的文本内容;如果你不用这种方法,不让 textarea完全显示,而仅仅是隐藏,例如使用 hidden="{{ showMask ? true :false }}",因为不涉及到 textarea的删除与重建,所以就无需添加 value属性来控制文本内容了。
  • textarea是可以输入可换行的文本内容的,所以这里使用了 rich-text组件,在使用的时候,我发现 rich-text好像不支持溢出隐藏,所以又额外在其外面包了一层 view组件,并将其高度设置为和 textarea相同。

上面四个步骤,都比较简单,稍微需要注意的是,如果 textarea的内容包含了换行文本,则需要对换行符进行处理:

textareaContent.replace(/\n/g, '<br/>')
如果你想让 textarea自动增加高度而不是固定高度,给 textarea加了个 auto-height,那么就需要“实时”获取其高度 说是 “实时”,其实也并不是那么实时,不考虑其他样式的变化, textarea的高度与行数有关,每增减一行,其高度才会变化,所以只需要监控其内容行数的变化即可,恰好 textarea组件也已经提供了这个监控器:bindlinechange
实例代码如下:
<view class="page-body">
<button bindtap="changeMaskVisible">切换mask</button>
<view class="textarea-wrp">
<textarea id="text-area" value="{{txtContent}}" bindinput='txtInput' bindlinechange="textAreaLineChange" wx:if="{{!showMask}}" auto-height />
<view class='rich-text' style="{{('height:' + txtHeight + 'px')}}" wx:else>
<rich-text nodes="{{txtRealContent}}"></rich-text>
</view>
</view>
<button>Footer</button>
<view wx:if="{{showMask}}" bindtap="changeMaskVisible" class="mask">
<view class="mask-content"></view>
</view>
</view>

样式:

.rich-text {
overflow: hidden;
}
.mask {
position: fixed;
top:;
right:;
bottom:;
left:;
background-color: rgba(0, 0, 0, .6);
z-index:;
}
.mask-content {
position: fixed;
top: 44%;
left: 50%;
height: 60%;
width: 60%;
transform: translate(-50%, -50%);
background-color: yellowgreen;
z-index:;
}

js:

Page({
data: {
txtRealContent: '',
txtContent: '',
showMask: false,
txtHeight: 0
},
textAreaLineChange(e) {
this.setData({ txtHeight: e.detail.height })
},
txtInput(e) {
this.setData({ txtContent: e.detail.value })
},
changeMaskVisible(e) {
if (!this.data.showMask) {
// 将换行符转换为wxml可识别的换行元素 <br/>
const txtRealContent = this.data.txtContent.replace(/\n/g, '<br/>')
this.setData({ txtRealContent })
}
this.setData({ showMask: !this.data.showMask })
}
})

微信小程序 — 自定义picker选择器弹窗内容+textarea穿透bug的更多相关文章

  1. picker-view、微信小程序自定义时间选择器(非官方)

    picker-view自定义时间选择器 官网的自定义时间选择器比较简陋.日期不准 下面是我自己写的一个demo <view class="baseList"> < ...

  2. 微信小程序 自定义省市选择器

    1.把省市数据放在city.js中,city.js放在until目录下 // city.js module.exports = { "province": [ { "ti ...

  3. 微信小程序自定义弹窗wcPop插件|仿微信弹窗样式

    微信小程序自定义组件弹窗wcPop|小程序消息提示框|toast自定义模板弹窗 平时在开发小程序的时候,弹窗应用场景还是蛮广泛的,但是微信官方提供的弹窗比较有局限性,不能自定义修改.这个时候首先想到的 ...

  4. 微信小程序----日期时间选择器(自定义精确到分秒或时段)

    声明 bug:由于此篇博客是在bindcolumnchange事件中做的值的改变处理,因此会出现当你选择时,没有点击确定,直接取消返回后,会发现选择框的值依然改变.造成原因:这一点就是由于在bindc ...

  5. 微信小程序自定义 tabbar

    一定的需求情况下,无法使用小程序原生的 tabbar 的时候,需要自行实现一个和 tabbar 功能一模一样的自制组件. 查阅了海量的博客和文档之后,亲自踩坑.总结了三种在不使用微信小程序原生 tab ...

  6. 微信小程序自定义组件,提示组件

    微信小程序自定义组件,这里列举了一个常用的提示自定义组件,调用自定义组件中的方法和字段.仅供参考和学习. 编写组件: 在根目录下添加“components”目录,然后像添加Page页面一样添加自定义组 ...

  7. 微信小程序——自定义导航栏

    微信头部导航栏可能通过json配置: 但是有时候我们项目需求可能需要自定义头部导航栏,如下图所示: 现在具体说一下实现步骤及方法: 步骤: 1.在 app.json 里面把 "navigat ...

  8. 微信小程序-自定义底部导航

    代码地址如下:http://www.demodashi.com/demo/14258.html 一.前期准备工作 软件环境:微信开发者工具 官方下载地址:https://mp.weixin.qq.co ...

  9. 微信小程序自定义tabbar的实现

    微信小程序自定义tabbar的实现 目的:当采用微信的自定义tabbar组件的时候,切换的时候会出现闪屏的效果:当使用微信默认的tabbar的时候,限制了tabbar的数量以及灵活配置. 方案:自己动 ...

随机推荐

  1. ASP.NET MVC Liu_Cabbage 个人博客

    RightControl_Blog 介绍 前台使用燕十三博客前端模板,后台基于RightControl .NET通用角色权限管理系统搭建,已完成.项目地址:http://www.baocaige.to ...

  2. 关于pageHelper无法查到总数踩到的坑

    问题代码 PageHelper.startPage(pageNum,pageSize); List<pojoVo> pojoVo=robotService.getPageList(); P ...

  3. P4118 [Ynoi2016]炸脖龙I

    思路:扩展欧拉定理 提交:\(\geq5\)次 错因:快速幂时刚开始没有判断\(a\)是否大于\(p\) 题解: 用树状数组维护差分,查询时暴力从左端点的第一个数向右端点递归,若递归时发现指数变为\( ...

  4. 使用 ALinq 实现 Linq to MySQL【转】

    http://www.cnblogs.com/huangcong/archive/2011/05/24/2055204.html

  5. vue中使用ckeditor,支持wps,word,网页粘贴

    由于工作需要必须将word文档内容粘贴到编辑器中使用 但发现word中的图片粘贴后变成了file:///xxxx.jpg这种内容,如果上传到服务器后其他人也访问不了,网上找了很多编辑器发现没有一个能直 ...

  6. vue中父组件如何监听子组件值的变化

    vue中我们会遇到很多父子组件通信的需求, 下面简单列一下,父子组件通信的几种情况 1:父组件向子组件传值:使用prop向子组件传值: 2:子组件实时监听父组件传来的值的变化:使用watch去监听父组 ...

  7. Liunx之nginx配置

    一.nginx安装 卸载yum安装的ngjnx yum remove nginx -y 编译安装nginx步骤 编译安装nginx的步骤 1.解决软件依赖 yum install gcc patch ...

  8. cesium地下模式(地表透明)1

    cesium没有提供地下功能,实现地下模式需要以下三步. 1.修改cesium源码,在GlobeSurfaceTileProvider.js文件里修改一行代码 command.pass = Pass. ...

  9. 解析NaN

    此文为自译文,且第一次翻译,有不足之处. 原英文地址:https://en.wikipedia.org/wiki/NaN 我的理解 32位下二进制的 NaN 存储格式为s111 1111 1111 1 ...

  10. servlet容器:jetty,Tomcat,JBoss

    一.几款servlet容器对比:jetty,Tomcat,JBoss 二.JBOSS相关问题解决 1.JBOSS下载安装 2.处理jboss-as-7.1.1.Final与jdk1.8及1.8以上版本 ...