本文主要介绍 div 标签设置 contenteditable = ' true ' 时,在光标位置插入输入的内容,或在光标位置粘贴纯文本内容。文中涉及知识,可参考以下: http://www.zhangxinxu.com/wordpress/2016/01/contenteditable-plaintext-only/
http://www.jb51.net/article/57650.htm
https://www.cnblogs.com/rainman/archive/2011/02/27/1966482.html
http://www.zhangxinxu.com/wordpress/2011/04/js-range-html%E6%96%87%E6%A1%A3%E6%96%87%E5%AD%97%E5%86%85%E5%AE%B9%E9%80%89%E4%B8%AD%E3%80%81%E5%BA%93%E5%8F%8A%E5%BA%94%E7%94%A8%E4%BB%8B%E7%BB%8D/
http://kjah.iteye.com/blog/422509
先搭好 html ,一个按钮用于插入操作,一个 div 实现 contenteditable 功能,及主要逻辑
<button type="button" id='insert'>插入标题</button> <div contentEditable="true" id="editor"> <h3>副标题</h3> <p>文本</p> </div>
接着是实现 js 逻辑功能
document.getElementById('insert').onclick=function(){ // 点击插入按钮时,系统弹框输入内容 var content = prompt('请输入内容'); // 防止编辑框没有获取焦点时点击,故加一个操作,使编辑框获取焦点 document.getElementById('editor').focus(); // 执行插入方法 if(!!content){ insertHtml('<h4>'+content+'</h4>'); } }
主要逻辑在 insertHtml 方法中
function insertHtml(html) { //Selection 对象,表示用户选择的文本范围或光标的当前位置。 //在非IE浏览器(Firefox、Safari、Chrome、Opera)下可以使用window.getSelection()获得selection对象 //anchor 选中区域的“起点”。 //focus 选中区域的“结束点”。 //range 是一种fragment(HTML片断),它包含了节点或文本节点的一部分。一般情况下,同一时刻页面中只可能有一个range,也有可能是多个range(使用Ctrl健进行多选,不过有的浏览器不允许,例如Chrome)。可以从selection中获得range对象,也可以使用document.createRange()方法获得。 var sel = window.getSelection(), range; if (sel.getRangeAt && sel.rangeCount) { //getRangeAt(index) 从当前selection对象中获得一个range对象。 range = sel.getRangeAt(0); //deleteContents()方法,range内容会被删除 range.deleteContents(); //将输入的内容写入并加载到 dom 中 var el = document.createElement("div"); el.innerHTML = html; var frag = document.createDocumentFragment(), node, lastNode; while ( (node = el.firstChild) ) { lastNode = frag.appendChild(node); } //insertNode,在range的开始位置插入一 个节点 range.insertNode(frag); //收尾 if (lastNode) { range = range.cloneRange(); range.setStartAfter(lastNode); range.collapse(true); sel.removeAllRanges(); sel.addRange(range); } } }
此时往编辑框里粘贴内容,会带上原本样式,显然不是我们要的结果,需对粘贴文本进行更改
document.getElementById('editor').onpaste=function(event){ var e = event || window.event // 阻止默认粘贴 e.preventDefault(); // 粘贴事件有一个clipboardData的属性,提供了对剪贴板的访问 // clipboardData的getData(fomat) 从剪贴板获取指定格式的数据 var text = (e.originalEvent || e).clipboardData.getData('text/plain') || prompt('在这里输入文本'); // 插入 document.execCommand("insertText", false, text); };
最后附上完整代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>contenteditable</title> <style> #insert{ width: 90px; height: 30px; border: 1px solid #ccc; background-color: #fff; margin: 10px; } #editor{ padding: 10px; overflow-y: auto; min-height:200px; border:1px solid #f33; outline: 0; } #editor h4{ margin: 10px 0; } </style> </head> <body> <button type="button" id='insert'>插入标题</button> <div contentEditable="true" id="editor"> <h3>副标题</h3> <p>文本</p> </div> </body> <script> document.getElementById('insert').onclick=function(){ var content = prompt('请输入内容'); document.getElementById('editor').focus(); if(!!content){ insertHtml('<h4>'+content+'</h4>'); } } document.getElementById('editor').onpaste=function(event){ var e = event || window.event e.preventDefault(); var text = (e.originalEvent || e).clipboardData.getData('text/plain') || prompt('在这里输入文本'); document.execCommand("insertText", false, text); }; function insertHtml(html) { var sel = window.getSelection(), range; if (sel.getRangeAt && sel.rangeCount) { range = sel.getRangeAt(0); range.deleteContents(); 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); if (lastNode) { range = range.cloneRange(); range.setStartAfter(lastNode); range.collapse(true); sel.removeAllRanges(); sel.addRange(range); } } } </script> </html>