在可编辑div中插入文字或图片的问题解决思路

转载 2016年05月31日 22:34:45

最近在网上碰到一个人问了我一个问题,在可编辑div中插入文字或者图片。因为web在线编辑器我从来只是用,基本不会去研究源代码。后来正好一个在线聊天web项目中也要用到这个功能,我就特地看看了代码。

基本上编辑器或者在线聊天web页面,是不太可能用textarea在做输入框的,因为我们可能要插入图片或者超级链接,因此选择在iframe或者div作为输入框是必须的。

我这里用的是 div.

要使div可编辑 必须 加入 contentEditable="true" 这个属性。

然后就是获取光标位置(或者选择文字位置)进行文字或者html的插入 。

由于火狐等标准浏览器支持getSelection方法,IE9以上也支持,但是万恶的iE6-8不支持,因此要分两部分代码来写。由于这些代码很简单,以下先贴一遍

function insertHTML(html)  
       {  
           var dthis=$("#div3")[0];//要插入内容的某个div,在标准浏览器中 无需这句话  
            var sel, range;  
            if (window.getSelection)  
             {  
                    // IE9 and non-IE  
                    sel = window.getSelection();  
                    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);  
                    }  
                   }  
            }   
            else if (document.selection && document.selection.type !='Control')   
            {  

                $(dthis).focus(); //在非标准浏览器中 要先让你需要插入html的div 获得焦点  
         ierange= document.selection.createRange();//获取光标位置  
                ierange.pasteHTML(html);    //在光标位置插入html 如果只是插入text 则就是fus.text="..."  
                $(dthis).focus();      

            }  
       }  

以上代码基本 完成了 在可编辑div中 插入指定的html内容,这些代码在baidu或者google中到处可以搜到,因此不再解释为什么这么写(太普遍了)

执行后 会发现在IE或者非标准浏览器中 是正常的。在火狐或者chrome中 就不正常了

譬如 以下页面 ,我有 不定数量的div(可能是程序动态生成),我只需要其中某一个div进行html的插入,其他不需要。

.....其他html元素.....

<div id="div1" contentEditable="true"  ></div>  

<div id="div2" contentEditable="true" ></div>  

 <div contentEditable="true"  id="div3"></div>  
 <input type="button" id="cmdInsert" onclick="执行向div3插入html方法"/>

如上页面 我只需要div3 支持插入html 其他两个 只是可编辑而已

使用上述代码会发现,如果最后一个失去焦点的是 div3 那么一切正常 如果 不是div3 或者 我又点到页面其他控件或者空白处,会发现插入的html没有插入到我们想要的div3中而是插入到了 其他地方。 这其实不是bug,而是正常现象,getSelection 可以横跨很多域,因此无法保证 获得出来的range一定是你需要的div 这里我再次申明,我实在不想看(哪怕看一眼)国内的在线web编辑器是如何实现的。经过我翻查了度娘和google发现有个思路可以解决。

其实我们要解决的就是一件事情,每当页面上的元素(包括div或者任意元素) 获得焦点又失去后,我们只需获得最后一个失去焦点的div是否是div3,如果是则执行上述代码,如果不是直接在div3的内容后面加入要插入的html(硬编码就可以。不要告诉我 不会)

一开始我想到的办法是对div3设置一个click事件以及focus事件,当鼠标点进去或者获得焦点时 把一个变量 譬如叫做 isdiv3 设置为true,点其他地方设置为false(这个方法实际上是行不通的,这里我就不多解释为什么行不通,有各种不同的情形可以导致即使获 得焦点,isdiv3依然不会被设置为true,而且需要对每个html元素设置事件让isdiv3变为false,这是很恐怖的事情)

这里我放出一种比较通用和不容易被干扰的解决办法。

首先在 页面的 最顶部写上

<style>   
  div:focus{z-index:100;}  // 这里随意你设置多少值,100只是举个列子<br> 

</style>

上面这个样式告诉我们,当只有div 获得焦点后 他会产生一个css属性就是 z-index被设置成了100,以任何形式失 去焦点 这个css属性就没了。当然你也可以设置其他的css属性。因为我们在点button执行函数的时候,div3也会失去焦点 (getSelection 依然存在)

以下思路就清晰了 我们再写一个函数

var lastFocusID="";  
function getFocus()  
       {  
        var divlist = document.getElementsByTagName('div');  
        for(var i=0; i<divlist.length; i++)  
         {  
            var ta = divlist.item(i);  
            if (window.getComputedStyle(ta, null).zIndex!=null && window.getComputedStyle(ta, null).zIndex == 100) {  
              if(ta.id && ta.id!=null)  
               lastFocusID=ta.id.toString();  
               else  
                lastFocusID="";  
               break;  
            }  
            else  
             lastFocusID="";  
         }  

       }  
 //再加入一个全屏事件  
      $(window).click(function(e)  
          {  
            if (window.getSelection)  
            {  
                 var getevent=e.srcElement?e.srcElement:e.target;//不要告诉我不知道这句的意思  

                if(getevent.tagName=="INPUT" && getevent.id!=null && getevent.id=="cmdInsert")  
                {  
                    //代表 点了插入html的按钮  
                    //则不执行getFocus方法  
                 }  
                else  
                  getFocus();//除非点了那个插入html的按钮 其他时候必须要执行getFocus来更新最后失去焦点的div  
            }  


          })


然后修改一下 insertHTML 这个方法  
    function insertHTML(html)  
       {  
           var dthis=$("#div3")[0];  
            var sel, range;  
            if (window.getSelection)  
             {  
                if(lastFocusID!="div3")  
               {  
               $("#div3).html(dthis.innerHTML+html)     ;//说明 用户可能在其他控件上 进行焦点或者其他操作 则
 return;//后面不执行了<br>  
                } 

。。。。。。。。。。//其他代码照旧 

这样就解决火狐或者chrome里面 会出现乱插入内容的现象。


转载自:http://www.9958.pw/post/div_edit_method

内容可编辑contenteditable

前言最近遇到一个问题:文本域的高度随输入内容的多少自适应,就像是这样的: 刚刚拿到这个问题,就想到用textarea来搞定,尝试了一下,虽然也搞定了,但总感觉有点麻烦。仔细思考一番,想到貌似h5...
  • xxxxxMiss
  • xxxxxMiss
  • 2016年04月06日 23:28
  • 4369

div可编辑状态设置

div,p标签等可以激活他们的可编辑状态 jQuery中 $("div").attr("contenteditable":"true");...
  • lovqc
  • lovqc
  • 2015年10月28日 16:57
  • 925

让div可编辑,设置标签的可读可写属性

添加contenteditable属性让文本处于可编辑状态,这里可以编辑
  • ning0_o
  • ning0_o
  • 2016年03月16日 15:51
  • 2283

jquery 实现可编辑DIV

给realprice开始的DIV绑定click事件. $("div[id^='realprice']").live('click',function(){    var divedit = $(...
  • billhepeng
  • billhepeng
  • 2012年03月29日 22:08
  • 4559

如何让DIV可编辑、可拖动示例代码

1、可编辑: 可编辑 设置contentEditable属性可以让div编程可编辑状态 2、可拖动: $('#move').draggable(); 使用jQuery ...
  • u011714480
  • u011714480
  • 2013年09月18日 16:10
  • 582

如何让div内可输入内容

在网上搜了一阵后,无果.随后在群里问了问,才知道div有一个 contentEditable(设置或获取表明用户是否可编辑对象内容的字符串。)属性.唉,看样有必要在回去看看html的内容了.代码:这里...
  • gangzhucoll
  • gangzhucoll
  • 2016年08月10日 16:45
  • 432

ContentEditable任意位置输入

ios中contenteditable无法输入的问题,添加-webkit-user-select: auto 即可解决 contentEditable任意位置输入...
  • Half_open
  • Half_open
  • 2016年11月24日 16:03
  • 608

可编辑DIV,输入图片

可编辑DIV div { min-width: 471px; min-height: 305px; b...
  • w695137400
  • w695137400
  • 2016年11月19日 21:06
  • 210

替换textarea的文本编辑框的实现,可现实文字输入与显示图片、表情

整理自网络 ------------------------------------------------------------------------------------------ 方...
  • lf124
  • lf124
  • 2015年07月29日 09:24
  • 4344

div设置contentEditable="true"作为文本编辑器,定位光标解决办法

比如你会在div中插入表情,也可能输入文字,这时候,你可能需要定位光标的位置,默认不处理的情况下,div的光标是定位在文字后面,而你插入一个img标签,光标是不会跟随移动的!解决办法: funct...
  • chiwenheng2078
  • chiwenheng2078
  • 2015年09月01日 15:10
  • 8232
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:在可编辑div中插入文字或图片的问题解决思路
举报原因:
原因补充:

(最多只允许输入30个字)