123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- export function isRegExp (value) {
- return Object.prototype.toString.call(value) === '[object RegExp]'
- }
- /**
- * 通用关键字高亮替换
- * @param {String} value 要高亮的字符串
- * @param {String|Array} oldChar 要被替换的字符串(或数组)
- * @param {String|Array} newChar 要替换成的字符串(或数组)
- *
- * 比如:要将 - `剑鱼标讯工具函数` 字符串中的 `工具` 高亮
- * 则此时 value -> `剑鱼标讯工具函数`
- * oldChar -> `工具`
- * newChar -> `<span class="highlight-text">工具</span>`
- *
- * 批量高亮-----
- * 比如:要将 - `剑鱼标讯工具函数` 字符串中的 `工具` `剑鱼` 高亮
- * 则此时 value -> `剑鱼标讯工具函数`批量高亮
- * oldChar -> ['工具', '剑鱼']
- * newChar -> ['<span class="highlight-text">', '</span>']
- *
- * 注意:此时newChar为一个长度为2的数组,数组中为高亮标签的起始标签和结束标签
- *
- */
- export function replaceKeyword(
- value,
- oldChar,
- newChar = ['<span class="highlight-text">', '</span>']
- ) {
- if (!oldChar || !newChar || oldChar === '略') return value
- // oldChar的字符串数组
- let oldCharArr = []
- if (Array.isArray(oldChar)) {
- oldCharArr = oldChar.concat()
- } else {
- oldCharArr.push(oldChar)
- }
- // 非字符串替换集合
- const notStrReplacer = []
- for (let i = 0; i < oldCharArr.length; i++) {
- if (!oldCharArr[i]) {
- continue
- } else {
- if (isRegExp(oldCharArr[i])) {
- // 正则直接替换
- // 注意:该正则中必须包含至少一个分组匹配,分组中的内容用来替换
- notStrReplacer.push(oldCharArr[i])
- oldCharArr[i] = ''
- } else {
- // 字符串替换
- oldCharArr[i] = oldCharArr[i].replace(/([\$\(\)\*\+\.\[\]\?\/\\\^\{\}\|])/g, '\\$1').replace(/\s+/g, '')
- // oldCharArr[i] = oldCharArr[i]
- // .replace(/([$()*+.[\]?/\\^{}|])/g, '\\$1')
- // .replace(/\s+/g, '')
- // oldCharArr[i] = oldCharArr[i].replace(/\$/g,"\\$");
- // oldCharArr[i] = oldCharArr[i].replace(/\(/g,"\\(");
- // oldCharArr[i] = oldCharArr[i].replace(/\)/g,"\\)");
- // oldCharArr[i] = oldCharArr[i].replace(/\*/g,"\\*");
- // oldCharArr[i] = oldCharArr[i].replace(/\+/g,"\\+");
- // oldCharArr[i] = oldCharArr[i].replace(/\./g,"\\.");
- // oldCharArr[i] = oldCharArr[i].replace(/\[/g,"\\[");
- // oldCharArr[i] = oldCharArr[i].replace(/\]/g,"\\]");
- // oldCharArr[i] = oldCharArr[i].replace(/\?/g,"\\?");
- // oldCharArr[i] = oldCharArr[i].replace(/\\/g,"\\");
- // oldCharArr[i] = oldCharArr[i].replace(/\//g,"\\/");
- // oldCharArr[i] = oldCharArr[i].replace(/\^/g,"\\^");
- // oldCharArr[i] = oldCharArr[i].replace(/\{/g,"\\{");
- // oldCharArr[i] = oldCharArr[i].replace(/\}/g,"\\}");
- // oldCharArr[i] = oldCharArr[i].replace(/\|/g,"\\|");
- }
- }
- }
- // 数组去空
- let lastArr = oldCharArr
- .filter((item) => !!item)
- .sort((a, b) => b.length - a.length)
- // 数组去重
- lastArr = Array.from(new Set(lastArr))
- if (lastArr.length === 0 && notStrReplacer.length === 0) {
- return value
- }
- if (notStrReplacer.length) {
- for (let j = 0; j < notStrReplacer.length; j++) {
- // 正则替换
- value = value.replace(notStrReplacer[j], newChar)
- }
- }
- const regExp = new RegExp(`(${lastArr.join('|')})`, 'gmi')
- if (Array.isArray(newChar)) {
- // 批量高亮
- return value.replace(regExp, newChar.join('$1'))
- } else {
- // 普通单个高亮
- return value.replace(regExp, newChar)
- }
- }
- /**
- * 富文本高亮专用替换,用于指定关键词包裹高亮,使用dom解析避免HTML标签被影响
- * @param htmlString - String
- * @param keyword - String
- * @param richChar - String $1
- */
- export function replaceKeywordWithRichText (
- htmlString,
- keyword,
- richChar = '<span class="highlight-text">$1</span>',
- skipClassName = ['highlight-text']
- ) {
- if (!keyword || !richChar || keyword === '略') return htmlString
- // 创建一个临时的DOM元素来解析HTML字符串
- const tempDiv = document.createElement('div')
- tempDiv.innerHTML = htmlString
- // 格式化需要替换的富文本
- const richString = richChar.replace(/\$1/g, keyword)
- const richTextNode = document.createElement('div')
- richTextNode.innerHTML = richString;
- function getRichNode () {
- return richTextNode.firstChild.cloneNode(true)
- }
- // 递归函数来遍历DOM节点并替换文本
- function replaceText(node) {
- if (node.nodeType === Node.TEXT_NODE && node.textContent.includes(keyword)) {
- // 创建一个文档片段来存放替换后的富文本和剩余文本
- const frag = document.createDocumentFragment()
- // 将文本分割为关键词前后的文本,以及替换的富文本
- const parts = node.textContent.split(keyword)
- for (let i = 0; i < parts.length; i++) {
- // 关键词替换为富文本
- if (parts.length > 1 && i !== 0) {
- frag.appendChild(getRichNode());
- }
- // 其他文本正常添加
- frag.appendChild(document.createTextNode(parts[i]))
- }
- // 替换原始文本节点
- node.parentNode.replaceChild(frag, node)
- } else if (node.nodeType === Node.ELEMENT_NODE) {
- // 如果是元素节点,递归其子节点
- const skip = skipClassName.some(sk => node.className.indexOf(sk) !== -1)
- // 跳过已经高亮的元素子节点
- if (!skip) {
- Array.from(node.childNodes).forEach(replaceText)
- }
- }
- }
- // 从临时div开始递归替换文本
- replaceText(tempDiv)
- // 返回修改后的HTML字符串
- return tempDiv.innerHTML
- }
- /**
- * 从key=value&key1=value1&key2=value2...中获取key值
- * @param {String} formString 目标字符串,必须为key=value&key1=value1的格式
- * @param {String} targetKey 要从目标字符串获取哪个key
- * @returns {String}
- */
- export function getFormValue(formString, targetKey) {
- let reg = new RegExp('(^|&)' + targetKey + '=([^&]*)(&|$)', 'i')
- let r = formString.match(reg) //获取url中'?'符后的字符串并正则匹配
- let context = ''
- if (r != null) context = r[2]
- // 释放变量
- reg = null
- r = null
- return context == null || context == '' || context == 'undefined' ? '' : context
- }
- /**
- * 从url中获取对应name的参数
- * @param {String} name
- * @returns {String}
- */
- export function getQueryParam(name) {
- const search = window.location.search
- let target = ''
- if (search) {
- const arr = search.split('?')
- if (arr[1]) {
- target = arr[1]
- }
- }
- const value = getFormValue(target, name)
- return decodeURIComponent(value)
- }
|