前段时间写一个商城,里面用到了物流信息,刚开始的时候只是把物流信息用text做了简单的展示,当用户快递单被派送的时候,也只能看到快递员的电话号码而不能直接拨打,对此深感不便,于是就想能不能写的自定义组件来实现这个功能?为此看了几个实现了该功能的小程序,看了一下他们的效果
效果:如果这条信息中有电话号码,电话号码高亮+下划线,点击的时候弹出拨打电话窗口,点击其他文本部分无效
思路:1,首先要看一下这个字符串中是否有电话号码,如果有提取出来,如果没有,就把它当成一段普通的文字处理就好了
2,把字符串按照一定的规则分割,加上标识放在数组中
3,通过不同的标识显示不同效果
代码:js
// component/telView/index.js
Component({
/**
* 组件的属性列表
*/
properties: {
/**所要显示的文本 */
nodes: {
type: String,
value: ""
}
},
/**
* 组件的初始数据
*/
data: {
},
ready: function() {
this.dealNodes()
},
/**
* 组件的方法列表
*/
methods: {
/**
* 检查是否有电话号码
*/
checkPhone: function(text) {
return text.match(/((((13[0-9])|(15[^4])|(18[0,1,2,3,5-9])|(17[0-8])|(147))\d{8})|((\d3,4|\d{3,4}-|\s)?\d{7,14}))?/g);
},
/**
* 处理文本
*/
dealNodes: function() {
const nodes = this.data.nodes
console.log("nodes==" + nodes.length)
let resultList = this.checkPhone(nodes)
resultList = resultList.slice(0, resultList.length - 1)//所得集合在原来的文本后面增加一个空格,所以要去掉
let phoneNums = []//电话号码集合
for (let i = 0; i < resultList.length; i++) {
if (resultList[i].length > 0) {
const phoneNumItem = {}
phoneNumItem.tel = resultList[i]//提取电话号码
phoneNumItem.index = i//该电话号码所对应的position
phoneNums.push(phoneNumItem)
}
}
let nodesList = []//最终分割的字符集合
if (phoneNums.length > 0) {
let startIndex = 0//截取开始位置
let endIndex = phoneNums[0].index//结束位置
let dlength = 0//电话号码所引起的差量
for (let j = 0; j < phoneNums.length; j++) {
const pItem = phoneNums[j]
let str1 = ""
if (startIndex != endIndex) {
str1 = nodes.substring(startIndex, endIndex)
console.log("index==" + j + "startIndex==" + startIndex + "endIndex==" + endIndex + "str1==" + str1)
}
startIndex = endIndex + pItem.tel.length
dlength += (pItem.tel.length - 1)
if (j == phoneNums.length - 1)
{
endIndex = nodes.length
} else {
endIndex = dlength + phoneNums[j + 1].index
}
const item = {}
item.text = str1
item.show_type = 0 //0 纯文本展示 1 电话号码
nodesList.push(item)
const itemTel = {}
itemTel.text = pItem.tel
itemTel.show_type = 1 //0 纯文本展示 1 电话号码
nodesList.push(itemTel)
if (j == phoneNums.length - 1) {
if (pItem.index < resultList.length - 1) {
const endItem = {}
const endStr = nodes.substring(startIndex, endIndex)
console.log("end== startIndex==" + startIndex + "endIndex==" + endIndex + "endStr==" + endStr)
endItem.text = endStr
endItem.show_type = 0 //0 纯文本展示 1 电话号码
nodesList.push(endItem)
}
}
}
} else {
const item = {}
item.text = nodes
item.show_type = 0 //0 纯文本展示 1 电话号码
nodesList.push(item)
}
this.setData({
nodesList: nodesList
})
},
/**
* 拨打电话
*/
makeCall: function(event) {
const tel = event.currentTarget.id
wx.makePhoneCall({
phoneNumber: tel,
})
}
}
})
json
{
"component": true,
"usingComponents": {}
}
wxml
<view class='view_tel'>
<block wx:for="{{nodesList}}" wx:key="{{index}}">
<block wx:if="{{item.show_type==0}}">{{item.text}}</block>
<span class='view_phone' wx:if="{{item.show_type==1}}" catchtap='makeCall' id='{{item.text}}'>{{item.text}}</span>
</block>
</view>
wxss
/* component/telView/index.wxss */
.view_tel {
display: flex;
font-size: 28rpx;
color: #888;
flex-wrap: wrap;
}
.view_phone {
color: red;
font-size: 28rpx;
text-decoration: underline;
background-color: transparent;
}
功能上是实现了,但是对于字符串处理那段代码不太满意,如果你有更有的解决办法,欢迎交流