可编辑的DIV -编辑器

 

找了好多,没几个好用的,都或多或少有问题

 

 

目前这个最好用。。  不过有一个奇葩的问题,就是要放在"<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 0;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(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);
    }
}


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("555");
    }
    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:#555;}
#editor {width:500px;height:200px;border:1px solid #ccc;margin:20px 0;padding:10px;}
li {display:inline;line-height:30px;margin-right:20px;font-size:14px;}
li span {display:inline-block;zoom:1;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(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);
    }
}

$(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=!1;
    this.start=0;
    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(.*)\]$/)[1];
    },
    getStart:function(){
        if (this.element.selectionStart || this.element.selectionStart == '0'){  
            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 > 0 ? sel.getRangeAt(0) : 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+1);
                    tempRange.setEnd(rang.endContainer, rang.endOffset+1);
                } 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(0,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 == '0'){
                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="50" rows="5">这里是文本框</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\'/>&nbsp;');"/> <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) + 1;
    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, "&nbsp;&nbsp;").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;
},1)
  
}
 
//锁定编辑器中鼠标光标位置。。
function _insertimg(str){
var selection= window.getSelection ? window.getSelection() : document.selection;
var range= selection.createRange ? selection.createRange() : selection.getRangeAt(0);
if (!window.getSelection){
document.getElementById('testdiv').focus();
var selection= window.getSelection ? window.getSelection() : document.selection;
var range= selection.createRange ? selection.createRange() : selection.getRangeAt(0);
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==13||e==32) { 
   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(0);
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 #000; overflow-x:hidden; overflow-y:auto; outline:none;}
.editbox img{ margin:0 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(0);
        range.insertNode(node);
    } else if (document.selection && document.selection.createRange) {
        range = document.selection.createRange();
        html = (node.nodeType == 3) ? 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(0);
        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://stackoverflow.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 = 0,
    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 + 1, val_index + str.length - 1);
}
//光标的当前位置
function getTextPos(obj){
    if(!obj || obj.offsetWidth == 0){ return false; }
    var t = obj, start = 0, end = 0, value = '', range, range_all;
    value = t.value;
    if(typeof(t.selectionStart) == "number"){
        start = t.selectionStart;
        end = t.selectionEnd;
    } 
    else if(document.selection && t.offsetWidth>0){
        t.focus();
        range = document.selection.createRange();
        if(range.parentElement() == t){
            range_all = document.body.createTextRange();
            range_all.moveToElementText(t);
            for(start = 0; range_all.compareEndPoints("StartToStart", range) < 0; start++){
                range_all.moveStart('character', 1);
            }
            for(var i = 0; i <= start; i++){
                if(t.value.charAt(i) == '\n'){
                    start++;
                }
            }
            range_all.moveToElementText(t);
            for(end = 0; range_all.compareEndPoints('StartToEnd', range) < 0; end++){
                range_all.moveStart('character', 1);
            }
            for(var i = 0; 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 == 0){ return false; }
    var t = obj, start = 0, end = 0, 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(0, 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 == 0){ 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:0;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: 124%;padding: 0;width: 475px;overflow:hidden;resize: none;position:absolute;left:62px; top:55px;outline: none;}
.button{width:100px;height:30px;background:url(button.gif) 0 0 no-repeat;position:absolute;left:442px;top:135px;}
.button:hover{background-position:0 -30px;}
.button:active{background-position:0 -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 0 7px;padding-left:14px;}
</style>
</head>

<body>
<div class="box">
    <textarea id="textarea" accesskey="1" tabindex="1" 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>

 

 

 

 

 

 

 

posted @ 2013-09-24 09:43  赵小磊  阅读(4207)  评论(0编辑  收藏  举报
回到头部