在做web版聊天程序时,往往需要将一个DIV设置为可编辑状态,并且可以插入表情。
插入表情时,不仅仅是在输入的文字最后追加表情,还可能在输入文本的中间,即光标位置插入表情(光标后还有文本)。
另外,还需要保证粘贴进来的文字必须是纯文本,不然百度搜索一篇文章粘贴进来,就太乱了。我们希望输入的文本都是纯文本,只有最基本的p标签或div标签。
通过各种百度搜索,我在项目中成功实施。
现将项目中的技术提取出来,形成一个小样例,大家可以参照使用。算是对网上提供这些素材的开发人员的回馈了。
html代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>可编辑的DIV(兼容IE8)</title>
<style type="text/css">
#content {
width: 500px;
height: 200px;
border: 1px solid #CCC;
}
</style>
<script src="../jquery.js"></script>
<script src="./contenteditable.js"></script>
</head>
<body>
<button id="insert" unselectable="on" onmousedown="return false">笑脸</button>
<div id="content" contenteditable="true"></div>
<script type="text/javascript">
// 在光标位置插入html代码,如果dom没有获取到焦点则追加到最后
function insertAtCursor(jsDom, html) {
if (jsDom != document.activeElement) { // 如果dom没有获取到焦点,追加
jsDom.innerHTML = jsDom.innerHTML + html;
return;
}
var sel, range;
if (window.getSelection) {
// IE9 或 非IE浏览器
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt(0);
range.deleteContents();
// Range.createContextualFragment() would be useful here but is
// non-standard and not supported in all browsers (IE9, for one)
var el = document.createElement("div");
el.innerHTML = html;
var frag = document.createDocumentFragment(),
node, lastNode;
while ((node = el.firstChild)) {
lastNode = frag.appendChild(node);
}
range.insertNode(frag);
// Preserve the selection
if (lastNode) {
range = range.cloneRange();
range.setStartAfter(lastNode);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
}
} else if (document.selection && document.selection.type != "Control") {
// IE < 9
document.selection.createRange().pasteHTML(html);
}
}
$('#insert').click(function() {
var html = ':)';
insertAtCursor(document.getElementById('content'), html);
});
</script>
</body>
</html>
contenteditable.js代码:
/**
* contenteditable="plaintext-only"在Firefox,ie浏览器中无效,这会导致DIV不可编辑。
* 通过监听粘贴动作,过滤纯文本放入可编辑DIV的光标位置
*/
$(function() {
$('[contenteditable]').each(function() {
// 干掉IE http之类地址自动加链接
try {
document.execCommand("AutoUrlDetect", false, false);
} catch (e) {}
$(this).on('paste', function(e) {
e.preventDefault();
var text = null;
if (window.clipboardData && clipboardData.setData) {
// IE
text = window.clipboardData.getData('text');
} else {
text = (e.originalEvent || e).clipboardData.getData('text/plain');
}
if (!text) {
return false; // 粘贴图片时
}
if (document.body.createTextRange) {
console.log('insert Text');
if (document.selection) {
textRange = document.selection.createRange();
} else if (window.getSelection) {
sel = window.getSelection();
var range = sel.getRangeAt(0);
// 创建临时元素,使得TextRange可以移动到正确的位置
var tempEl = document.createElement("span");
tempEl.innerHTML = "&#FEFF;";
range.deleteContents();
range.insertNode(tempEl);
textRange = document.body.createTextRange();
textRange.moveToElementText(tempEl);
tempEl.parentNode.removeChild(tempEl);
}
textRange.text = text;
textRange.collapse(false);
textRange.select();
} else {
// Chrome之类浏览器
document.execCommand("insertText", false, text);
}
});
// 去除Crtl+b/Ctrl+i/Ctrl+u等快捷键
$(this).on('keydown', function(e) {
// e.metaKey for mac
if (e.ctrlKey || e.metaKey) {
switch (e.keyCode) {
case 66: //ctrl+B or ctrl+b
case 98:
case 73: //ctrl+I or ctrl+i
case 105:
case 85: //ctrl+U or ctrl+u
case 117:
e.preventDefault();
break;
}
}
});
});
});