1.0 需求背景
需求很常見,就是當(dāng)一行文字過多時(shí),顯示省略號(hào),然后顯示展開兩個(gè)字,點(diǎn)擊,文字完全展示開,點(diǎn)擊收起,回到省略形式,如下圖
2.0 需求分析
有了上圖,應(yīng)該能更好理解,讓我們再來細(xì)致分析下思路:
- 一行省略號(hào),這個(gè)沒啥難度,css可以實(shí)現(xiàn)(至于多行,差別不大)
- 展開和收起,初步構(gòu)想是,收起狀態(tài)時(shí)是通過css控制的省略號(hào),那展開時(shí),我們可以移除省略號(hào)的css,這樣只需要添加、移除類名即可
-
如何確定當(dāng)前行是否有省略號(hào)?這個(gè)問題,之前想過字體大小+屏幕寬度來計(jì)算一行最多能放下多少個(gè)字,實(shí)際發(fā)現(xiàn),不夠準(zhǔn)確,后面想到另外一種方案;
通過兩個(gè)盒子嵌套,外面大盒子只有一行文字高度,并且溢出隱藏,內(nèi)層盒子就正常顯示,當(dāng)內(nèi)層盒子高度 > 外層盒子,那么一定有省略號(hào),故可以確定如下結(jié)構(gòu)
<!-- 外層盒子,固定只顯示一行 -->
<view class="outer" style="height: {{outerHeight}}{{outerHeight == 'auto' ? '' : 'px'}}">
<!-- 內(nèi)層盒子,正常擺放,但是要?jiǎng)討B(tài)添加省略號(hào)類名 -->
<view
class="inner {{ show ? '' : 'ellipsis' }} "
style="padding-right: {{ show ? '0' : paddingRight }}px;">
{{text}}
</view>
</view>
- **如何確定一行文字的高度呢?**由于考慮到組件的通用性,筆者這里想了一個(gè)辦法,寫一個(gè)dom,將其定位到頁面看不見的地方,然后獲取一下,并且這里面的字體大小由外部傳入,這樣就能保證,不管怎么設(shè)置都可以準(zhǔn)確獲取
<!-- 用于獲取一行高度dom -->
<view class="get-height" >
獲取一行高度的盒子
</view>
3.0 具體實(shí)現(xiàn)
上面列舉了幾個(gè)問題,以及解決思考,現(xiàn)在我們就來具體實(shí)現(xiàn)
首先,獲取dom高度肯定是需要的,這里把它簡單封裝下
/**
* 獲取dom信息
* **/
getHeight(selector) {
return new Promise((resolve,reject) => {
const query = wx.createSelectorQuery().in(this)
query.select(selector).boundingClientRect(function(res){
resolve(res)
}).exec()
})
},
剩下的,大概就是高度差的判斷,決定是否有省略號(hào),以及動(dòng)態(tài)添加、移除css類名,這個(gè)過程不算復(fù)雜
其實(shí)還有一個(gè)問題,就是,當(dāng)確定要顯示省略號(hào)時(shí),右邊切換的dom是需要定位到當(dāng)前行的末尾,同時(shí),當(dāng)前行業(yè)需要一個(gè)padding,而這個(gè)padding就是切換按鈕的寬度,所以這里也有一點(diǎn)點(diǎn)邏輯
4.0 完整如下
html
<view class="intercept" style="font-size: {{fontSize}};" >
<!-- 外層盒子,固定只顯示一行 -->
<view class="outer" style="height: {{outerHeight}}{{outerHeight == 'auto' ? '' : 'px'}}">
<view
class="inner {{ show ? '' : 'ellipsis' }} "
style="padding-right: {{ show ? '0' : paddingRight }}px;">
{{text}}
</view>
</view>
<view
wx:if="{{ heightInfo.realHeight > heightInfo.baseHeight }}"
class="collapse {{show ? 'collapse-fold' : ''}}"
bindtap="toggle" >
{{show ? '收起' : '展開'}}
</view>
<!-- 用于獲取一行高度dom -->
<view class="get-height" >
獲取一行高度的盒子
</view>
</view>
js
// components/interceptText/interceptText.js.js
Component({
/**
* 組件的屬性列表
*/
properties: {
text: {
type: String,
value: ''
},
fontSize: {
type: String,
value: '28rpx'// 單位rpx
}
},
/**
* 組件的初始數(shù)據(jù)
*/
data: {
heightInfo: {
baseHeight: 0,
realHeight: 0
},
show: true,
// 需要?jiǎng)討B(tài)設(shè)置的外層盒子高度
outerHeight: 0,
paddingRight: 0
},
lifetimes: {
async attached() {
this.calculateHeight()
},
},
/**
* 組件的方法列表
*/
methods: {
/**
* 動(dòng)態(tài)獲取展開文字寬度
* 確保展開、收起文字能顯示
* **/
async getCollapseWidth() {
let res = await this.getHeight('.collapse')
if(!res) return
this.setData({
paddingRight: `${res.width}` || 30
})
},
/**
* 計(jì)算高度差,判斷是否有省略號(hào)
* **/
async calculateHeight() {
return Promise.all([this.getHeight('.get-height'),this.getHeight('.inner')]).then((res) => {
let [baseRes,realRes] = res
let baseHeight = parseInt(baseRes.height || 0)
let realHeight = parseInt( realRes.height || 0)
if(!baseHeight || !realHeight) {
this.setData({
outerHeight: 'auto',
})
return
}
this.setData({
heightInfo: {
baseHeight,
realHeight
},
outerHeight: baseHeight,
show: !(realHeight > baseHeight)
})
// 計(jì)算展開、收起
wx.nextTick(() => {
this.getCollapseWidth()
})
})
},
/**
* 獲取dom信息
* **/
getHeight(selector) {
return new Promise((resolve,reject) => {
const query = wx.createSelectorQuery().in(this)
query.select(selector).boundingClientRect(function(res){
resolve(res)
}).exec()
})
},
/**
* 展開狀態(tài)切換
* **/
toggle() {
this.setData({
show: !this.data.show,
outerHeight: this.data.show ? this.data.heightInfo.baseHeight : this.data.heightInfo.realHeight
})
},
}
})
css文章來源:http://www.zghlxwxcb.cn/news/detail-491215.html
.intercept{
position: relative;
}
.outer{
overflow: hidden;
}
.get-height{
position: absolute;
z-index: -9999;
top: -100%;
left: -100%;
height: auto;
}
.ellipsis{
display: -webkit-box;
text-overflow: ellipsis;
overflow: hidden;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
}
.collapse{
position: absolute;
right: 0;
bottom: 0;
width: fit-content;
color: #1989fa;
}
.collapse-fold{
position: unset;
}
5.0 總結(jié)
筆者認(rèn)為,實(shí)現(xiàn)該功能的難點(diǎn)是如何判斷當(dāng)前行是否應(yīng)該省略,這里采取一個(gè)高度差的辦法,基本就沒有兼容性問題,不過實(shí)際中發(fā)下,文字會(huì)有閃爍,這是因?yàn)楦叨榷际莿?dòng)態(tài)計(jì)算導(dǎo)致的,展開、收起,可能改為插槽更合適點(diǎn)文章來源地址http://www.zghlxwxcb.cn/news/detail-491215.html
到了這里,關(guān)于微信小程序?qū)崿F(xiàn)一個(gè)文字展開收起功能的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!