小程序 textarea组件层级过高导致文字穿透浮层的一个解决方法

在小程序中,当使用textarea组件并弹出浮层时,textarea的文字会穿透遮罩层。本文介绍了两种解决方法:一是通过隐藏textarea并在弹窗关闭时恢复;二是使用替代元素保持页面稳定性。详细阐述了解决过程和技术要点。
部署运行你感兴趣的模型镜像

最近做的一个小程序需求,其中一个页面使用到了 textarea这个小程序组件,然后点击页面上的某个元素,会触发页面弹起一个弹窗,这时发现 textareaplaceholder文字或者输入的文字内容,会直接穿透遮罩层和浮动弹窗,显示在最上面,开始时我以为是遮罩层和浮动弹窗的层级舍得小了,于是改大,谁知道没用,改到了 99999也没用,于是我意识到这应该不是我代码的问题,网上一搜,果然有故事。

这里写图片描述

解决方案

  • 隐藏 textarea

这是最简单的解决手段,一般弹窗的时候,都会带个遮罩层,把遮罩层下面的内容隐藏一部分,用户基本上不会注意的,然后再去掉弹窗和遮罩层的时候再把 textarea显示出来。
这种方法简单有效,大部分情况下都可以这么解决。

<textarea wx:if="{{ showMask }}"></textarea>
  • 使用替代元素

有时候, 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

这里写图片描述


原理说完了,完整实例代码如下:

index.wxml

<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>

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 })
  }
})

index.wxss

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

您可能感兴趣的与本文相关的镜像

AutoGPT

AutoGPT

AI应用

AutoGPT于2023年3月30日由游戏公司Significant Gravitas Ltd.的创始人Toran Bruce Richards发布,AutoGPT是一个AI agent(智能体),也是开源的应用程序,结合了GPT-4和GPT-3.5技术,给定自然语言的目标,它将尝试通过将其分解成子任务,并在自动循环中使用互联网和其他工具来实现这一目标

微信小程序中的textarea组件由于其原生特性,层级固定且无法通过z-index直接调整,这在滚动视图或弹窗等场景下会造成布局问题。根据提供的资料《解决微信小程序textarea层级问题及业务场景应对策略》,可以采用策略模式来动态管理不同元素的显示,以适应不同的业务场景。 参考资源链接:[解决微信小程序textarea层级问题及业务场景应对策略](https://wenku.youkuaiyun.com/doc/6401ac85cce7214c316ec275?spm=1055.2569.3001.10343) 具体实现上,可以在textarea组件周围使用其他视图(view)元素,分别用于显示placeholder、已输入的文本等。利用textarea的`bindfocus`和`bindblur`事件来控制其他视图的显示与隐藏,这样可以根据textarea是否有焦点来切换显示内容。例如,当textarea获得焦点时,显示输入视图,而当失去焦点时,显示placeholder视图。 此外,针对滚动场景,可以在底部操作栏上方设置一个遮罩(mask),这个遮罩可以是一个透明度较低的视图元素,用来遮挡textarea的上半部分内容,防止它覆盖底部操作栏。在textarea失去焦点时,通过调整遮罩的透明度来显示底部操作栏,从而保证用户界面的可用性。 总之,通过动态切换元素的显示状态和使用遮罩,可以有效解决textarea层级造成的问题。建议开发者在实际应用中根据具体情况选择合适的策略,并且持续关注微信小程序官方文档的更新,以便及时调整解决方案。 参考资源链接:[解决微信小程序textarea层级问题及业务场景应对策略](https://wenku.youkuaiyun.com/doc/6401ac85cce7214c316ec275?spm=1055.2569.3001.10343)
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值