最近再开发一款前端的即时通信产品,记录一些比较有价值的使用方法;
div变输入框
.text_msg{
box-sizing: border-box;
outline: none;
white-space: pre-line;
word-break: break-all;
word-break: break-word;
overflow-y: auto;
}
<div contenteditable="true" id="speakBox"></div>
提交正则
const str = speakEl.innerHTML;
// 这一行的处理是为了用户使用按键换行,比方说Ctrl+Enter换行,需要手动在输入框插入<br>进行换行
result = result.replace(/<br>/g, '[换行]');
// 把换行替换为'\n', 这一行的处理是为了用户使用按键换行
result = result.replace(/\[换行\]/g, function(hh: string) {
return '\n';
});
// 把空格替换为空字符串
result = result.replace(/ /g, function(hh: string) {
return '';
});
// 提交判断是否为空
const isEmpty = result.replace(/\s/g, '');
if (isEmpty === '') {
console.log('消息不能为空');
return;
};
把光标移动到最后
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, '');