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

摘要:
最近在网上碰到一个人问了我一个问题,在可编辑div中插入文字或者图片。='Control'){$.focus();//在非标准浏览器中要先让你需要插入html的div获得焦点ierange=document.selection.createRange();//获取光标位置ierange.pasteHTML;//在光标位置插入html如果只是插入text则就是fus.text="..."$.focus();}}以上代码基本完成了在可编辑div中插入指定的html内容,这些代码在baidu或者google中到处可以搜到,因此不再解释为什么这么写执行后会发现在IE或者非标准浏览器中是正常的。

最近在网上碰到一个人问了我一个问题,在可编辑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   contentEditable="true"  ></div>  
  
<div   contentEditable="true" ></div>  
  
 <div contentEditable="true"  id="div3"></div>  
 <input type="button"   onclick="执行向div3插入html方法"/>

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

    1. 使用上述代码会发现,如果最后一个失去焦点的是div3那么一切正常如果不是div3或者我又点到页面其他控件或者空白处,会发现插入的html没有插入到我们想要的div3中而是插入到了其他地方。
    2. 这其实不是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里面会出现乱插入内容的现象。

当然这只是一个思路,欢迎大家提供更好的办法和性能更高的思路。

免责声明:文章转载自《在可编辑div中插入文字或图片的问题解决思路》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇攻防世界-web-i-got-id-200(perl文件上传+ARGV造成任意文件读取和任意命令执行)CSS实例:翻转图片、滚动图片栏、打开大门下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

EasyUI:datagrid数据汇总

EasyUI:datagrid数据汇总 js代码: var total=0;//全局变量 $(function(){ $('#tablebudgetdata').datagrid({ title:' ', //标题 onLoadSuccess: function (data) {//表单加载完后再加载此方...

H50073:div 循环添加点击事件,swiper循环添加点击事件

1,div 循环添加点击事件 <div class="video home_video"> <div class="videolist"vpath="4.mp4"ipath="4.mp4"><img src="../common/images/theme/default/video_icon.png"&...

DOCTYPE html PUBLIC 指定了 HTML 文档遵循的文档类型定义

今天看到一篇CSS应用的一个友好搜索,我按网页上的代码复制、粘贴后预览时总达不到效果,而直接拷贝他的实例却能达到效果,开始以为书写顺序不对,于是调整书写顺序,还是不行,最后找到了我认为最没什么用处的第一行才发现真正起作用的竟然是<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional //EN"...

039.PGSQL-备份和恢复-增量备份-开启wal归档、并设置定时清理备份之后的wal文件

备份: sql转储备份 文件系统级别备份 连续归档-增量备份和基于时间点恢复(PITR) 物理备份:将数据目录,参数文件拷贝出来 逻辑备份:将数据库对象导出到文件 冷备份:数据库关闭情况下 热备份:数据库启动情况下 RTO 恢复时间目标  故障发生到恢复所需时间 RPO 恢复点目标   可容忍丢失多少数据  一、增量备份 定期对数据库做基础备份,再配合WA...

day18_文件的上传和下载学习笔记

1、文件上传的原理分析 什么是文件上传?    要将客户端(浏览器)数据存储到服务器端,而不将数据直接存储到数据库中,而是要将数据存储到服务器所在的磁盘上,这就要使用文件上传。为什么使用文件上传?    通过文件上传,可以将浏览器端的数据直接保存到服务器端。不将数据保存到数据库中,而是保存到服务器磁盘上,这样减少了数据库服务器的压力,对数据的操作更加灵活...

帝国CMS 复制word里面带图文的文章,图片可以直接显示

1.4.2之后官方并没有做功能的改动,1.4.2在word复制这块没有bug,其他版本会出现手动无法转存的情况 本文使用的后台是Java。前端为Jsp(前端都一样,后台如果语言不通得自己做 Base64编码解码) 因为公司业务需要支持IE8 ,网上其实有很多富文本框,效果都很好。 例如www.wangEditor.com  但试了一圈都不支持IE8 。 所...