备注:最近再开发一款前端的即时通信产品,记录一些比较有价值的使用方法;
css消息显示
.text_msg{
white-space: pre-line;
word-break: break-all;
word-break: break-word;
}
js找到['微笑替换表情']
export function ImHandleTextMessageEmoteShow(text: string, searchText?: string) {
text = text.replace(/(?=\[)(.*?)(\])/g, function(tmp) {
// 获取图片url
return handleEmojiTextToUrl(tmp);
});
// 搜索高亮
if (searchText && searchText.length > 0) { // 如果有搜索的时候
return text.replace(searchText,'<span style=\'color: #58AEFF;\'>'+searchText+'</span>');
};
return text;
};
// vue 使用v-html react使用 <span dangerouslySetInnerHTML={{__html: str}}></span>
div变输入框
<div contenteditable="true"></div>
把光标移动到最后
andleKeepLastIndex() {
// vue3 ref绑定;可以通过document.getById(targetName)获取
const speakRefVal: any = speakRef.value;
if (window.getSelection) {
speakRefVal.focus();
var range = window.getSelection();
range.selectAllChildren(speakRefVal);
range.collapseToEnd();
/* 第二种方法
var sel = window.getSelection();
var range = document.createRange();
range.selectNodeContents(speakRefVal);
range.collapse(false);
sel.removeAllRanges();
sel.addRange(range);*/
};
},
监听回车和ctr回车
// vue3 @keydown="handleSpeakKey($event)"
// 监听按键_步骤1 监听Ctrl+Enter
handleSpeakKey(event: any) {
if(event.ctrlKey && event.keyCode === 13){
return false;
}else if (event.keyCode === 13) {
event.preventDefault() // 阻止浏览器默认换行操作
return false
}
},
处理复制
/* 个人建议图片单独上传,不要图文混排,虽然能实现,但是遇到bug能难解决 */
// vue3 ref绑定语法
speakRefVal.onpaste = function(e: any) {
e.stopPropagation();
e.preventDefault();
const selection = getSelection();
if (!selection) return;
lastEditRange = selection.getRangeAt(0);
if (!(e.clipboardData && e.clipboardData.items) ) {
return ;
};
const items = e.clipboardData.items;
if (items.length) {
let item = items[0];
if (item.kind === "string") {
item.getAsString(function (str: string) {
if (!str) return;
let tmpStr = HTMLEncode(str);
let Span = `<div>${tmpStr}</div>`;
methods.handleInsertContent(Span);
})
}
if (item.kind === "file") {
var pasteFile = item.getAsFile();
if (pasteFile.type === "image/png") {
Dialog.confirm({
title: '图片上传',
message: '确定上传该图片吗?',
}).then(() => {
methods.handlePasteImgUpload(pasteFile);
}).catch(() => {
});
// var reader = new FileReader()
// reader.onload = function(event: any) {
// let Img = `<div><img src="${event.target.result}"/></div>`;
// methods.handleInsertContent(Img);
// };
// reader.readAsDataURL(pasteFile);
};
}
}
}
记录最后一次光标位置
// vue3 ref绑定语法
speakRefVal.onblur = function() {
const selection = getSelection();
if (!selection) return;
lastEditRange = selection?.getRangeAt(0);
};
将标签插入到光标位置
handleInsertContent(Element: string) {
// 获取光标对象
const selection: any = getSelection();
if (!selection) return;
selection.addRange(lastEditRange);
// 获取当前光标位置
const range = selection.getRangeAt(0);
// 创建Dom
const node = range.createContextualFragment(Element);
// 获取当前元素最后一个子元素
const c = node.lastChild;
// 插入创建Dom
range.insertNode(node);
// 插入成功后光标移动到插入Dom后面
if (c) {
range.setEndAfter(c);
range.setStartAfter(c);
};
},
文本框移动到最后
var tObj = document.getElementById('searchInput');
var sPos = tObj.value.length;
setCaretPosition(tObj, sPos);
function setCaretPosition(tObj, sPos) {
if (tObj.setSelectionRange) {
tObj.setSelectionRange(sPos, sPos);
tObj.focus();
} else if (tObj.createTextRange) {
var rng = tObj.createTextRange();
rng.move('charcter', sPos);
rng.select();
}
}
聊天框需要的正则
// 去除所有标签
str.replace(/<[^>]+>/g, "");
// 去除html所有标签,img除外
str.replace(/<(?!img).*?>/g, '');