react-native的输入框中实现插入高亮文本图片的做法

15,672次阅读
没有评论

共计 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 来实现这个功能。

今天文章暂时分享到这里。

    正文完
     0
    Yojack
    版权声明:本篇文章由 Yojack 于1970-01-01发表,共计2390字。
    转载说明:
    1 本网站名称:优杰开发笔记
    2 本站永久网址:https://yojack.cn
    3 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行删除处理。
    4 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
    5 本站所有内容均可转载及分享, 但请注明出处
    6 我们始终尊重原创作者的版权,所有文章在发布时,均尽可能注明出处与作者。
    7 站长邮箱:laylwenl@gmail.com
    评论(没有评论)