共计 2390 个字符,预计需要花费 6 分钟才能阅读完成。
背景
上一篇文章我们介绍了 rn 中如何实现文本高亮,但是输入框中实现文本高亮如何做呢?输入框中插入图片等如何实现呢?这篇文章将普及一下这方面的知识,分享给大家。
输入框高亮文本
其实假如你要实现输入框高亮文本,那么可以通过如下方式实现。
showBar()} onBlur={() => (Platform.OS == 'ios' ? hideKeyboard() : null)} multiline={true} textAlign={'left'} style={{textAlignVertical: 'top'}} onKeyPress={onKeyPressfn} onTextInput={onTextInput} className={Style['publish-textarea']} placeholder='haorooms 发布帖子测试'>
{matchAtData?.length> 0 ? (
{textData
.filter((li) => li.trim())
.map((item, index) => {if (matchAtData.join('').indexOf(item) != -1) {
return item ? (
{item}
) : null
} else {return {item}
}
})}
>
) : (textValue)}
这种方式可以实现文本框里面高亮文本了。
输入框里面插入图片如何实现呢?
假如需要插入图片,上面方式 ios 不兼容,插入多张图片的时候都不兼容,如何解决呢?只能利用 react-native-webview 通过富文本的形式实现。假如通过富文本实现,那么出来的数据结构是如下的:
' 你好 haorooms 博客
@haorooms 博客
# 文本高亮话题
这里是 rn 的渲染 ';
rn 里面出现这种富文本,后端存储 2 种方式,一种直接存储,这样的话,前台展示的时候也要通过富文本渲染出来。第二种我们可以通过转换为 json 字符串的形式来存储。例如可以转换为如下:
[{
type: 'div',
text: '你好 haorooms 博客'
}, {
type: 'span',
text: '@haorooms 博客',
id: '1'
}, {
type: 'span',
text: '# 文本高亮话题',
id: '2'
}, {
type: 'div',
text: '这里是 rn 的渲染'
}]
将 html 转换为 json 字符串,需要一些编译解析。我是这么解析的:
1、html 转为 josn
const operateHtmlToData = (html) => {
// 改进的正则表达式
const regex = /]*)?>([^|]*)?>([^/g, 'n')
_tagText = _tagText.replace(/ /g, ' ')
const obj = {
type: tagName,
text: _tagText
}
if (tagAttrs) {const attrs = tagAttrs.split(' ')
for (const attr of attrs) {const [key, values] = attr.split('=')
if (key === 'data-id') {obj.id = values.replace(/("|')/g, '')
}
}
}
if (obj.text || obj.id) {
// 只添加有内容或 id 的对象
result.push(obj)
}
} else if (inlineTagName) {let _inlineTagText = inlineTagText.trim()
_inlineTagText = _inlineTagText.replace(/
/g, 'n')
_inlineTagText = _inlineTagText.replace(/ /g, ' ')
const obj = {
type: inlineTagName,
text: _inlineTagText
}
if (inlineTagAttrs) {const attrs = inlineTagAttrs.split(' ')
for (const attr of attrs) {const [key, values] = attr.split('=')
if (key === 'data-id') {obj.id = values.replace(/("|')/g, '')
}
}
}
if (obj.text || obj.id) {
// 只添加有内容或 id 的对象
result.push(obj)
}
} else if (plainText) {
// 对于不在任何 HTML 标签内的纯文本
let trimmedText = plainText.trim()
trimmedText = trimmedText.replace(/
/g, 'n')
trimmedText = trimmedText.replace(/ /g, ' ')
if (trimmedText && plainText != '/div>') {
// 只添加非空文本
result.push({
type: 'text',
text: trimmedText
})
}
}
}
return result
}
2、json 转为 html
const renderElement = (element) => {switch (element.type) {
case 'div':
return `${element.text}`
case 'at':
return `${element.text}`
case 'text':
return element.text
default:
return null
}
}
const renderData = value.map((item) => renderElement(item)).join('')
setTextValue(renderData)
这种方式存储,列表也展示也是可以通过循环数组直接展示出来。但是需要遇到 div 的时候强制换行,span 的时候不换行,需要在 rn 里面实现这个功能。那么可以利用 view 包裹一层 text 来实现这个功能。
今天文章暂时分享到这里。
正文完