事情原由:(uni-app中 -> 会编译成小程序的那种哦)
新需求是:做一个记事本的功能,记录用户输入的文字,并且文字有下划线。
这里肯定要用到 textarea 标签对叭。
然后开始思考:下划线怎么添加?动态添加?....思索一阵后,得出的结论是不可行的,但是总要尝试的是叭(可是自己内心是拒绝的,
因为感觉是无用功嘛),
没办法,
然后就疯狂google,
结果发现,都没有好的idea,真的香菇了~~
竟然都香菇了,那为啥还要写这篇内容呢,主要是为了告诉大家,下次遇到这个需求,能避则避吧,实在避不了。只能换需求实现了。
需求效果展示(具体见代码描述):
html代码:(代码布局很简单,不涉及逻辑)
<template>
.......
//这里是点击某个按钮,弹出记事本区域哦,然后在这个区域里面,点击添加按钮,就新增一个记事本区域内容的那种
<view>点击记事本按钮,弹出记事本区域</view>
//这里是弹出记事本区域的地方哦
<view class="notepadlist-container">
<scroll-view scroll-y="true">
<view class="notepadlist-detail v-for="(item,index) in notepadList" :key="index" >
<view>{{item.title}}</view>
<view class="textarea-content">
<textarea :value="item.content" maxlength="-1" fixed
:data-index="index" @input="getTextareaContent" class="text-area"></teatarea>
</view>
...
</view>
</scroll-view>
<view @click="add">添加记事本</view>
</view>
</templte>
<script>
export default{
data(){
return{
notepadList:[]
}
},
methods:{
add(){
this.push({
title:'',
content:''
})
}
}
}
</script>
尝试解决的方案:
方案一:
使用css属性: text-decoration:underline;
直接设置在 textarea 标签上面
测试结果: pc浏览器上面可以正常显示,文字下划线可以添加上。但是小程序上面就不能正常显示。 pass掉此方案。
方案二:
使用图片的方式,图片的内容就是一根线,要注意高度哦。
然后给 textarea 设置为背景图片。(插一嘴,在小程序中,背景图片只支持两种方式,base64格式 或者 网络图片)
感觉还有个硬性要求:要固定字数。(但是,我这个需求是没有限制用户输入字数的嘛,固定字数的话,要把maxlength=-1去掉重新设置哦)
具体写法:
.text-area{
background:url('下划线的那种图片路径') repeat;
border:none;
outline:none;
overflow:hidden;
line-height:40rpx;//这里要注意 行高 要和 背景图片高度一致哦
resize:none;
}
目前结果,机型iPhone6下面(即开发者工具测试效果) 界面确实能出现看似完美的文字下划线。但是因为没有限制用户输入字数,多输入几行文字
就会出现 字和下划线重叠了,其他机型效果也不好。 只能pass掉此方案
方案三:(https://www.it1352.com/870070.html)
这里必须要把这位老哥的网址贡献出来,个人感觉,不管是pc还是小程序,视觉效果还不错的。但是由于追求理想状态,还是得pass掉此方案。
如果pc需要给textarea标签加下划线,强烈安利这种方式。
<textarea class="text-area"></textarea>
.text-area{
background-image:linear-gradient(left,white 10px,transparent 10px),
linear-gradient(right,white 10px,transparent 10px),
linear-gradient(white 30px,#ccc 30px,#ccc 31px,shite 31px);
//这里老哥写了兼容,嘿嘿,我就偷个懒,就不写了,-moz-linear-gradient,-ms-linear-gradient,-o-linear-gradient
background-image:-webkit-linear-gradient.......
background-size:100% 100%,100% 100%,100% 31rpx;
border-radius:10px;
box-shadow:inset 0 1px 2px rgba(0,0,0,.1);
line-height:31px;
padding:10px;
}
方案四:
说是写个text标签,用来装输入内容,点击text,就显示textarea,textarea失去焦点,就隐藏textarea标签。
这个方法的缺点就是,有些手机需要点击两次才能唤起 输入键盘,这样子体验效果更不好了,所以 pass 掉此方案。但是还是要实际操作一次,
~~
将这里的内容替换一下:
<view class="textarea-content">
<text @click="showTextarea(index)" v-if="!item.showTextarea">{{item.content}}</text>
<textarea value="item.content" v-if="item.showTextarea"
:data-index="index" @focus="focusTextarea" @blur="blurTextarea" @input="getTextareaContent"
maxlength="-1" fixed></textarea>
</view>
//js里面
focusTextarea(e){
let index = e.currentTarget.dataset.index;
this.notepadList[index].showTextarea = true;
}
blurTextarea(e){
let index = e.currentTarget.dataset.index;
this.notepadList[index].showTextarea = false;
}
showTextarea(index){
this.notepadList[index].showTextarea = !this.notepadList[index].showTextarea;
}
add(){
this.notepadList.push({
title:'',
content:'',
showTextarea:true
})
}
方案五:
这里采用动态设置 textarea 的高度以及 行高, 下划线采用 view 循环行数来设置 尝试一波,结果发现体验极不好,pass掉此方案
上面代码替换
<view class="textarea-content">
//这个view 表示设置的下划线,采用定位的方式哦
<view class="border-line" v-for="items in item.lineCount"
:style="{'top':getTop(items,item.lineHeight)+'rpx'}"></view>
<textarea :value="item.content" :data-index="index"
@linechange="getLineChange" @input="getTextarea" maxlength="-1"
:style="{'height':getHeight(item.lineHeight,item.lineCount)+'rpx',
'line-height':item.lineHeight+'rpx'}"></textarea>
</view>
//js
add(){
this.notepadList.push({
title:'',
content:'',
lineCount:1,
lineHeight:40 //这里默认一个行高
})
}
getLineChange(e){
let lineCount = e.detail.lineCount;
let index = e.currentTarget.dataset.index;
this.notepadList[index].lineCount = lineCount;
this.notepadList[index].lineHeight = e.detail.heightRpx / e.detail.lineCount;
},
getHeight(lineHeight,lineCount){
return (lineCount+1)*lineHeight
} //好吧,这里的方法是一样的,可以使用其中一个即可,哈哈哈哈哈,懒得换了,就多写了一个
getTop(lineCount,lineHeight){
return (lineCount+1)*lineHeight
}
方案六:
不动态设置 textarea 的高多,直接使用属性里面的 auto-height
上面代码替换:
<view class="textarea-content">
<textarea :value="item.content" :data-index="index" maxlength="-1"
auto-height="true" @input="getTextareaContent" ></textarea>
</view>
为什么会pass掉这个方案呢?是因为 在某些机型下,点击添加按钮,textarea 的高度会先变大后变为自己设定的高度,视觉效果不好,以及
有些机型,在textarea里面设置placeholder,这个内容会根据屏幕滚动而移动,体验也不好,所以 pass掉此方案。
讲真,肝不动了,赶脚江郎才尽了~~~