找了好多,没几个好用的,都或多或少有问题
目前这个最好用。。 不过有一个奇葩的问题,就是要放在"<a></a>"标签里面, js或者jQuery获取 $("#list a").click() 就可以了。。。
$("#list a").click(function(){
var oBtn = "<button contenteditable='false'>@ "+ $(this).find(".name").text() +"</button>";
$("#oEditor").focus();
insertHtmlAtCaret(oBtn);
});
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Div编辑器</title>
<style type="text/css">
#editor {width:500px;height:200px;border:1px solid #ccc;margin:20px ;padding:10px;}
</style>
</head> <body> <div id="editor" contenteditable="true">这是一个输入框...</div>
<a href="javascript:;" id="active">插入文字</a>
<a href="javascript:;" id="active2">插入btn</a>
<a href="javascript:;" id="active3">插入图片</a> <script type="text/javascript">
function insertHtmlAtCaret(html) {
var sel, range;
if (window.getSelection) {
// IE9 and non-IE
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt();
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);
}
} window.onload = function(){
var oEditor = document.getElementById("editor");
var oActive = document.getElementById("active");
var oActive2 = document.getElementById("active2");
var oActive3 = document.getElementById("active3");
oActive.onclick = function(){
oEditor.focus();
insertHtmlAtCaret("");
}
oActive2.onclick = function(){
oEditor.focus();
insertHtmlAtCaret("<button>tttt</button>");
}
oActive3.onclick = function(){
oEditor.focus();
insertHtmlAtCaret("<img src='http://mat1.gtimg.com/www/images/qq2012/qqlogo_1x.png' width='134' />");
}
}
</script> </body>
</html>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Div编辑器</title>
<style type="text/css">
a {text-decoration:none;color:#;}
#editor {width:500px;height:200px;border:1px solid #ccc;margin:20px ;padding:10px;}
li {display:inline;line-height:30px;margin-right:20px;font-size:14px;}
li span {display:inline-block;zoom:;vertical-align:middle;}
button {background:none;border:none;}
</style>
</head> <body> <div id="editor" contenteditable="true">这是一个输入框...</div>
<!-- <a href="javascript:;" id="active">插入文字</a>
<a href="javascript:;" id="active2">插入btn</a>
<a href="javascript:;" id="active3">插入图片</a> --> <ul id="list">
<li>
<a href="javascript:;">
<span class="head"><img src="http://qlogo3.store.qq.com/qzone/619611422/619611422/30?1349166380" alt=""></span>
<span class="name">小名</span>
</a>
</li>
<li>
<a href="javascript:;">
<span class="head"><img src="http://qlogo3.store.qq.com/qzone/619611422/619611422/30?1349166380" alt=""></span>
<span class="name">林兆禄</span>
</a>
</li>
<li>
<a href="javascript:;">
<span class="head"><img src="http://qlogo3.store.qq.com/qzone/619611422/619611422/30?1349166380" alt=""></span>
<span class="name">小红</span>
</a>
</li>
<li>
<a href="javascript:;">
<span class="head"><img src="http://qlogo3.store.qq.com/qzone/619611422/619611422/30?1349166380" alt=""></span>
<span class="name">小张</span>
</a>
</li>
</ul> <script type="text/javascript" src="http://s.rc.umfun.com//view/javascript/jQuery191_v1.js"></script>
<script type="text/javascript">
function insertHtmlAtCaret(html) {
var sel, range;
if (window.getSelection) {
// IE9 and non-IE
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt();
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);
}
} $(function(){
$("#list a").click(function(){
var oBtn = "<button contenteditable='false'>@ "+ $(this).find(".name").text() +"</button>";
$("#oEditor").focus();
insertHtmlAtCaret(oBtn);
});
}); /*window.onload = function(){
var oEditor = document.getElementById("editor");
var aActive = document.getElementById("list").getElementsByTagName("li"); for(var i=0; i<aActive.length; i++){
aActive[i].onclick = function(){
var oBtn = "<button contenteditable='false'>@ "+ this.innerHTML +"</button>";
oEditor.focus();
insertHtmlAtCaret(oBtn);
}
}
}*/
</script> </body>
</html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>光标控制器</title>
<script type="text/javascript">
function cursorControl(a){
this.element=a;
this.range=!;
this.start=;
this.init();
};
cursorControl.prototype={
init:function(){
var _that=this;
this.element.onkeyup=this.element.onmouseup=function(){
this.focus();
if(document.all){
_that.range=document.selection.createRange();
}else{
_that.start=_that.getStart();
}
}
},
getType:function(){
return Object.prototype.toString.call(this.element).match(/^\[object\s(.*)\]$/)[];
},
getStart:function(){
if (this.element.selectionStart || this.element.selectionStart == ''){
return this.element.selectionStart;
} // else if (window.getSelection){
// var rng = window.getSelection().getRangeAt(0).cloneRange();
// rng.setStart(this.element,0);
// return rng.toString().length;
// }
},
insertText:function(text){
this.element.focus();
if(document.all){
document.selection.empty();
this.range.pasteHTML(text) //this.range.text = this.range.pasteHTML(text);
this.range.collapse();
this.range.select();
}
else{
if(this.getType()=='HTMLDivElement'){
//this.element.innerHTML=this.element.innerHTML.substr(0,this.start)+text+this.element.innerHTML.substr(this.start);
// Begain of The Content added by bedweather
var sel = window.getSelection();
var rang = sel.rangeCount > ? sel.getRangeAt() : null;
if (rang == undefined
|| rang == null
|| (rang.commonAncestorContainer.id !="editdiv"
&& rang.commonAncestorContainer.parentNode.id !="editdiv")){
this.element.focus();
rang = document.createRange();
rang = selectNode(this.element);
rang.setStart(range.getEndContainer, rang.endOffset);
}
rang.deleteContents();
rang.insertNode(rang.createContextualFragment(text));
var tempRange = document.createRange();
var a = document.getElementById("editdiv")
tempRange.selectNodeContents(a);
if(rang.commonAncestorContainer.id == "editdiv"){
tempRange.setStart(rang.endContainer, rang.endOffset+);
tempRange.setEnd(rang.endContainer, rang.endOffset+);
} else {
tempRange.setStartAfter(rang.endContainer.nextSibling);
tempRange.setEndAfter(rang.endContainer.nextSibling);
}
sel.removeAllRanges();
sel.addRange(tempRange);
this.element.focus();
// End of The Content added by bedweather }else{
this.element.value=this.element.value.substr(,this.start)+text+this.element.value.substr(this.start);
};
}
},
getText:function(){
if (document.all){
var r = document.selection.createRange();
document.selection.empty();
return r.text;
}
else{
if (this.element.selectionStart || this.element.selectionStart == ''){
var text=this.getType()=='HTMLDivElement'?this.element.innerHTML:this.element.value;
return text.substring(this.element.selectionStart,this.element.selectionEnd);
}
else if (window.getSelection){
return window.getSelection().toString()
};
}
}
};
var c1,c2;
window.onload=function(){
c1=new cursorControl(document.getElementById('text'));
c2=new cursorControl(document.getElementById('editdiv'));
};
function fn1(str){
c1.insertText(str);
};
function fn2(str){
c2.insertText(str);
};
function fn3(){
alert(c1.getText());
};
function fn4(){
alert(c2.getText());
}
</script>
</head>
<body>
<input type = "button" value = "插入字符串 {文本1}" onclick="fn1('{文本1}');"/><input type = "button" value = "获取选中的文本" onclick="fn3();"/><br /> <br />
<textarea id="text" cols="" rows="">这里是文本框</textarea><br /><br />
<input type = "button" value = "插入字符串 {文本2}" onclick="fn2('{文本2}');"/> <input type = "button" value = "获取选中的文本" onclick="fn4();"/><br /> <br />
<input type = "button" value = "插入图片" onclick="fn2('<img src=\'http://s1.hao123img.com/index/images/newlogo-186X68.png\'/> ');"/> <input type = "button" value = "获取选中的文本" onclick="fn4();"/><br /> <br />
<div id="editdiv" contentEditable="true">这里是一个可编辑层</div><br />
</body>
</html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Language" content="zh-cn" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>DIV可编辑框鼠标光标处插入图片或者文字。</title>
<script type="text/javascript" src="http://www.w3school.com.cn/jquery/jquery.js
"></script>
<script type="text/javascript">
$(function(){
$(".imgbox img").click(function(){
$("#testdiv").focus();
var sy = $(".imgbox img").index(this) + ;
var img_url = "<img src='faceimg/"+sy+".gif'>"; /*此处如果不是插入图片可这样:
var img_url = "插入测试的文字";
*/
_insertimg(img_url); })
//注:如果要插入的是那种“快捷发言,快捷留言”里的文字,只需把那些文字都分别放在A标签里即可,然后img_url=a标签里面的内容。工作中的编辑器终于搞定!能插入图片和快捷发言和表情图片等。
}) //监控粘贴(ctrl+v),如果是粘贴过来的东东,则替换多余的html代码,只保留<br>
function pasteHandler(){
setTimeout(function(){
var content = document.getElementById("testdiv").innerHTML;
valiHTML=["br"];
content=content.replace(/_moz_dirty=""/gi, "").replace(/\[/g, "[[-").replace(/\]/g, "-]]").replace(/<\/ ?tr[^>]*>/gi, "[br]").replace(/<\/ ?td[^>]*>/gi, " ").replace(/<(ul|dl|ol)[^>]*>/gi, "[br]").replace(/<(li|dd)[^>]*>/gi, "[br]").replace(/<p [^>]*>/gi, "[br]").replace(new RegExp("<(/?(?:" + valiHTML.join("|") + ")[^>]*)>", "gi"), "[$1]").replace(new RegExp('<span([^>]*class="?at"?[^>]*)>', "gi"), "[span$1]").replace(/<[^>]*>/g, "").replace(/\[\[\-/g, "[").replace(/\-\]\]/g, "]").replace(new RegExp("\\[(/?(?:" + valiHTML.join("|") + "|img|span)[^\\]]*)\\]", "gi"), "<$1>");
if(!$.browser.mozilla){
content=content.replace(/\r?\n/gi, "<br>");
}
document.getElementById("testdiv").innerHTML=content;
},) } //锁定编辑器中鼠标光标位置。。
function _insertimg(str){
var selection= window.getSelection ? window.getSelection() : document.selection;
var range= selection.createRange ? selection.createRange() : selection.getRangeAt();
if (!window.getSelection){
document.getElementById('testdiv').focus();
var selection= window.getSelection ? window.getSelection() : document.selection;
var range= selection.createRange ? selection.createRange() : selection.getRangeAt();
range.pasteHTML(str);
range.collapse(false);
range.select();
}else{
document.getElementById('testdiv').focus();
range.collapse(false);
var hasR = range.createContextualFragment(str);
var hasR_lastChild = hasR.lastChild;
while (hasR_lastChild && hasR_lastChild.nodeName.toLowerCase() == "br" && hasR_lastChild.previousSibling && hasR_lastChild.previousSibling.nodeName.toLowerCase() == "br") {
var e = hasR_lastChild;
hasR_lastChild = hasR_lastChild.previousSibling;
hasR.removeChild(e)
}
range.insertNode(hasR);
if (hasR_lastChild) {
range.setEndAfter(hasR_lastChild);
range.setStartAfter(hasR_lastChild)
}
selection.removeAllRanges();
selection.addRange(range)
}
} //监控按enter键和空格键,如果按了enter键,则取消原事件,用<BR/ >代替。此处还等待修改!!!!!!如果后端能实现各个浏览器回车键产生的P,div, br的输出问题话就无需采用这段JS、
function enterkey(){
e = event.keyCode;
if (e==||e==) {
var keyCode = event.keyCode ? event.keyCode : event.which ? event.which : event.charCode;
event.returnValue = false; // 取消此事件的默认操作
if(document.selection && document.selection.createRange){
var myRange = document.selection.createRange();
myRange.pasteHTML('<br />');
}else if(window.getSelection){
var selection = window.getSelection();
var range = window.getSelection().getRangeAt();
range.deleteContents();
var newP = document.createElement('br');
range.insertNode(newP);
}
//alert(document.getElementById("testdiv").innerHTML)
}
}
</script>
<style type="text/css">
.editbox{width:400px;height:200px;border:1px solid #; overflow-x:hidden; overflow-y:auto; outline:none;}
.editbox img{ margin: 3px; display:inline;}
</style>
</head>
<body>
<div id="testdiv" contenteditable="true" class="editbox" onkeydown="enterkey()" >可以在任意文字后面插入图片或者文字哦!<br /></div>
<div class="imgbox">
<img src="faceimg/1.gif">
<img src="faceimg/2.gif">
<img src="faceimg/3.gif">
<img src="faceimg/4.gif">
</div> <script type="text/javascript">
//此处必须防止在最下端。
var edt = document.getElementById("testdiv");
if(edt.addEventListener){
edt.addEventListener("paste",pasteHandler,false);
}else{
edt.attachEvent("onpaste",pasteHandler);
}
</script>
</body>
</html>
下面这两个插入图片有点问题。
If all you want to do is insert some content at the cursor, there's no need to find its position explicitly. The following function will insert a DOM node (element or text node) at the cursor position in all the mainstream desktop browsers:
function insertNodeAtCursor(node) {
var range, html;
if (window.getSelection && window.getSelection().getRangeAt) {
range = window.getSelection().getRangeAt();
range.insertNode(node);
} else if (document.selection && document.selection.createRange) {
range = document.selection.createRange();
html = (node.nodeType == ) ? node.data : node.outerHTML;
range.pasteHTML(html);
}
}
If you would rather insert an HTML string:
function insertHtmlAtCursor(html) {
var range, node;
if (window.getSelection && window.getSelection().getRangeAt) {
range = window.getSelection().getRangeAt();
node = range.createContextualFragment(html);
range.insertNode(node);
} else if (document.selection && document.selection.createRange) {
document.selection.createRange().pasteHTML(html);
}
}
UPDATE
Following the OP's comments, I suggest using my own Rangy library, which adds a wrapper to IETextRange
object that behaves like a DOM Range. A DOM Range consists of a start and end boundary, each of which is expressed in terms of a node and an offset within that node, and a bunch of methods for manipulating the Range. The MDC article should provide some introduction.
http://*.com/questions/2213376/how-to-find-cursor-position-in-a-contenteditable-div
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<script>
//插入话题
function inTopic(id, str){
var str = str || "请在这里输入自定义话题";
str = "#" + str + "#";
var reg = new RegExp(str),
oTextarea = document.getElementById(id),
oValue = oTextarea.value,
val_index = ,
val_match,
val_pos;
if(reg.test(oValue)){
val_match = oValue.match(reg);
val_index = val_match.index;
}
else{
val_pos = getTextPos(oTextarea);
val_index = val_pos.start;
rangeText(oTextarea, str);
}
selectText(oTextarea, val_index + , val_index + str.length - );
}
//光标的当前位置
function getTextPos(obj){
if(!obj || obj.offsetWidth == ){ return false; }
var t = obj, start = , end = , value = '', range, range_all;
value = t.value;
if(typeof(t.selectionStart) == "number"){
start = t.selectionStart;
end = t.selectionEnd;
}
else if(document.selection && t.offsetWidth>){
t.focus();
range = document.selection.createRange();
if(range.parentElement() == t){
range_all = document.body.createTextRange();
range_all.moveToElementText(t);
for(start = ; range_all.compareEndPoints("StartToStart", range) < ; start++){
range_all.moveStart('character', );
}
for(var i = ; i <= start; i++){
if(t.value.charAt(i) == '\n'){
start++;
}
}
range_all.moveToElementText(t);
for(end = ; range_all.compareEndPoints('StartToEnd', range) < ; end++){
range_all.moveStart('character', );
}
for(var i = ; i <= end; i++){
if(t.value.charAt(i) == '\n'){
end++;
}
}
}
}
else{
start = value.length;
end = value.length;
}
return{
start: start,
end: end
}
}
//光标处替换的文本
function rangeText(obj, val, num){
if(!obj || obj.offsetWidth == ){ return false; }
var t = obj, start = , end = , value = '', val_start = '', val_end = '', pos;
var userAgent = navigator.userAgent.toLowerCase(), ie = /msie/.test(userAgent) && !/opera/.test(userAgent);
if(ie && t.nodeName.toLocaleLowerCase() != 'textarea'){
t.value = val;
t.focus;
return;
}
value = t.value;
pos = getTextPos(t);
start = pos.start;
end = pos.end;
if (typeof num=='number'){
start = start - num;
}
val_start = value.substring(, start);
val_end = value.substring(end);
t.value = val_start + val + val_end;
if (typeof num=='number'){
end = end - num;
}
selectText(t,end+val.length,end+val.length);
}
//光标定位到指定文本
function selectText(obj, start, stop){
if(!obj || obj.offsetWidth == ){ return false; }
var range;
if(obj.setSelectionRange){
obj.setSelectionRange(start,stop);
}
else{
range = obj.createTextRange();
range.collapse(true);
range.moveStart("character",start);
range.moveEnd("character",stop-start);
range.select();
}
obj.focus();
}
</script>
<style type="text/css">
body{margin:;background-image:url(miaov.jpg);}
.box{width:600px;height:200px;background:url(weibo.png) no-repeat;margin:60px auto;position:relative;}
#textarea{ border: medium none;font-size: 14px;height: 70px;line-height: %;padding: ;width: 475px;overflow:hidden;resize: none;position:absolute;left:62px; top:55px;outline: none;}
.button{width:100px;height:30px;background:url(button.gif) no-repeat;position:absolute;left:442px;top:135px;}
.button:hover{background-position: -30px;}
.button:active{background-position: -60px;}
.topic{position:absolute;left:72px;top:136px;height:26px;line-height:26px;text-decoration:none;color:#fff;font-size:12px;background:url(topic.gif) no-repeat 7px;padding-left:14px;}
</style>
</head> <body>
<div class="box">
<textarea id="textarea" accesskey="" tabindex="" style="font-family: Tahoma,宋体;"></textarea>
<a href="http://www.miaov.com" class="button"></a>
<a href="###" class="topic" onclick="inTopic('textarea','妙味课堂')">话题</a>
</div>
</body>
</html>