React-native中高亮文本实现方案

17,366次阅读
没有评论

共计 2071 个字符,预计需要花费 6 分钟才能阅读完成。

前言

React-native 中高亮文本实现方案,rn 中文本高亮并不像 h5 那样,匹配正则,直接添加标签实现,rn 中一般是循环实现了。一般是一段文本,拆分出关键词,然后关键词高亮。

简单实现

const markKeywords = (text, highlight) => {if (!text || !highlight) return {value: [text], highlight: []}

    for (let index = 0; index  item),
        hightList: highlight.map(item => item)
    }
} 

上面可以拆分出可以循环的文本,和要高亮的文本。

特殊情况

const title = 'haorooms 前端博文章高亮测试一下'
const highLightWords = ['前端博文', '文章高亮']

因为打上 星号 标记的原因,文章高亮 在被标记成 前端博文 章高亮 后,并不能被 文章高亮 匹配,而且即使能匹配也不能把 前端博文章高亮 拆成 前端博文 文章高亮 ,如果能拆成 前端博文章高亮 就好了。

function sort(letter, substr) {letter = letter.toLocaleUpperCase()
  substr = substr.toLocaleUpperCase()
  var pos = letter.indexOf(substr)
  var positions = []
  while(pos> -1) {positions.push(pos)
     pos = letter.indexOf(substr, pos + 1)
  }

  return positions.map(item => ([item, item + substr.length]))
}

// 高亮词第一次遍历索引
function format (text, hight) {var arr = []
  // hight.push(hight.reduce((prev, curr) => prev+curr), '')
  hight.forEach((item, index) => {arr.push(sort(text, item))
  })

  return arr.reduce((acc, val) => acc.concat(val), []);
}

// 合并索引区间
var merge = function(intervals) {
  const n = intervals.length;

  if (n  a[0] - b[0]);

  let refs = [];
  refs.unshift([intervals[0][0], intervals[0][1]]);

  for (let i = 1; i  a[0] - b[0]);
}

function getHightLightWord (text, hight) {var bj = merge(format(text, hight))
  const c = text.split('')
  var bjindex = 0
  try {bj.forEach((item, index) => {item.forEach((_item, _index) => {c.splice(_item + bjindex, 0, '**')
          bjindex+=1
      })
    })
  } catch (error) { }
  return c.join('').split('**')
}

export const markKeywords = (text, keyword) => {if (!text || !keyword || keyword.length === 0) {return { value: [text], keyword: []}
  }
  if (Array.isArray(keyword)) {keyword = keyword.filter(item => item)
  }
  let obj = {value: [text], keyword };
  obj = {value: getHightLightWord(text, keyword).filter((item) => item),
    keyword: keyword.map((item) => item),
  };
  return obj;
};

述方法中我们先使用了下标匹配的方式,得到一个下标值的映射,然后通过区间合并的方式把连着的词做合并处理,最后再用合并后的下标值映射去打 ** 标记即可。

简单组件封装

function TextHighLight(props) {const { title = '', highLightWords = [] } = props
    const {numberOfLines, ellipsizeMode} = props
    const {style} = props

    const {markKeywordList, hightList} = markKeywords(title, highLightWords)

    return 
            {
                markKeywordList ?
                    markKeywordList.map((item,index) => ((hightList && hightList.some(i => (i.toLocaleUpperCase().includes(item) || i.toLowerCase().includes(item))))
                            ? {item}
                            : item
                    ))
                    : null
            }
        
}

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