JavaScript Iframe富文本编辑器中的光标定位
最近在项目中碰到一个比较棘手的问题:
在iframe富文本编辑器中,有个工具栏,这个工具栏在iframe标签之外,工具栏上有一个按钮,点击该按钮向iframe正在编辑中的光标处插入一个图片,图片会插入到当前光标所在的位置。但由于需求的需要,点击该按钮后需要弹出一个详细选项浮动层,选择详细的类型后再插入,如此,问题来了,当我点击了该按钮,浮动层显示出来后,iframe已经失去焦点,并不知道之前正在编辑的位置,所以编辑器默认把图片插入到编辑器内容的最前边(内部处理),编辑器及浮动层需求如下图:
解决尝试
一、利用模态弹出框
首先声明这种方式是可行的,因为模态对话框会保持iframe编辑器的编辑状态,模态对话框的返回值可直接插入到之前正在编辑的光标位置,就像上面图中其他按钮一样,它们通过点击事件直接插入。但是对于上述需求,只是在该按钮位置添加了一个子类型选择列表框,用模态窗口显然得不到更好的人性化体验,这也不是我们所想要的。
这时候如果能保存之前光标的编辑位置就好了,的确,在按钮的点击事件中,弹出浮动层的同时也保存好光标的位置,然后选择了详细类型后再将光标还原到原来的位置插入图片信息,经过尝试和摸索,令人欣喜的是,这种方式是可行的。
二、保存光标位置,选择后还原(1)
这种方法主要通过document的selection对象来实现,在按钮的点击事件处理程序中,获取当前光标据文档开头的位置(即长度),然后保存,在选择了子类型后,根据之前保存的位置还原光标,然后插入图片信息,代码片段如下:
//记录光标的位置,以备后续还原使用
var LastPos = 0;
//保存当前光标的位置
function SaveCusorPos() {
//获取编辑器焦点
var wobj = document.getElementById("myiframe").contentWindow;
wobj.focus();
if (document.selection) {
//ie,利用范围进行计算
var sText = wobj.document.selection.createRange();
//清除掉当前选中的内容
if (sText.htmlText != undefined && sText.htmlText != "") {
wobj.document.selection.clear();
}
//选择当前光标位置到文档开头之间的内容(以字符为单位)
sText.moveStart('character', -wobj.document.body.innerHTML.toString().length);
//计算选择内容的长度
LastPos = sText.text.length + FliterHtmlTag(sText.htmlText) + 1; //; //sText.htmlText.length; //
}
else if (wobj.selectionStart || wobj.selectionStart == "0") {
//firefox,直接读取编辑位置
LastPos = wobj.selectionStart;
}
}
上述代码不难理解,在ie中需要用范围计算当前光标位置距离文档开头的距离,而在firefox中,直接可以用编辑对象获取当前的编辑位置,下面是光标还原的代码:
//把光标还原到之前保存的位置
function SetCusorPos() {
//获取编辑器对象焦点
var wobj = document.getElementById("myiframe").contentWindow;
wobj.focus();
if (wobj.document.body.setSelectionRange) {
//firefox,直接通过函数定位光标
wobj.document.body.setSelectionRange(LastPos, LastPos);
}
else if (wobj.document.selection.createRange()) {
//ie,用selection对象进行选择
var range = wobj.document.selection.createRange();
range.collapse(true);
//将选择区域的开始位置和结束位置都移动到之前保存的点
range.moveEnd('character', LastPos);
range.moveStart('character', LastPos);
//定位光标的位置
range.select();
}
}
在不同的浏览器中,处理方式均不一样,不过有一点是相通的,它们都是通过将选取的开始位置和结束位置重合来定位光标。
经测试,这种方式是可行的,但它只能在纯文本处理的时候有用(IE中),问题在于这个保存点的计算,通过选区Text的length获取的长度是只是这个选区的文字长度,它并不能过滤多媒体元素(如图片、音视频等),这些元素在这个length中并没有包括,故存在多媒体元素的时候,这个光标保存点是不准的,会在实际位置的前面插入。此外,选区还有另外一个属性htmlText,获取它的长度又如何呢!?答案也是不行,这个长度包含了选区中html标签的所有字符,比如换行,段落等都被计算在内,这个光标保存点比实际的要大的多,会在实际位置的后面插入。
二、保存光标位置,选择后还原(2)
上述两种方法都有自己的缺陷,经过摸索和查阅相关资料,在IE中有第三种方法可以实现此功能,就是selection对象的getBookmark和moveToBookmark两个方法,前者获取一个对象,这个对象记录了当前编辑器中光标的位置信息,后者根据这个位置信息还原光标的位置。代码如下:
//存储之前光标位置信息的对象
var ieSelectionBookMark = null;
//保存当前光标的位置
function SaveCusorPos() {
//编辑器获取焦点
var wobj = document.getElementById("myiframe").contentWindow;
wobj.focus();
if (document.selection) {
//获取当前光标的位置
var rangeObj = wobj.document.selection.createRange();
ieSelectionBookMark = rangeObj.getBookmark();
}
}
//把光标还原到之前保存的位置
function SetCusorPos() {
//编辑器获取焦点
var wobj = document.getElementById("myiframe").contentWindow;
wobj.focus();
if (ieSelectionBookMark) {
//还原光标的位置
var rangeObj = wobj.document.selection.createRange();
rangeObj.moveToBookmark(ieSelectionBookMark);
rangeObj.select();
ieSelectionBookMark = null;
}
}
上述代码改写了第二种方法中的两个函数,比较简洁,但这种方式在IE8中测试通过,其他不同版本浏览器中有待进一步验证,其他浏览器如firefox,利用第二种方式就可以实现。
如今浏览器五法八门,各自对标准的支持也不一样,导致了前端开发者做了大量的工作来弥补兼容性,不管怎样,相信会越来越好~~~
JavaScript Iframe富文本编辑器中的光标定位的更多相关文章
- php 解析富文本编辑器中的hmtl内容,富文本样式正确输出
说明:富文本编辑器中的内容在直接获获取后需要解析以后才能在页面中正确显示 我在后端这样处理: $content = htmlspecialchars_decode($info['intro']); h ...
- 【JavaScript】富文本编辑器
这是js写的富文本编辑器,还存在一些bug,但基本功能已经实现,通过这个练习,巩固了js富文本编辑方面的知识,里面包含颜色选择器.全屏.表情.上传图片等功能,每个功能实际对应的就是一个小插件啦 部分程 ...
- 过滤富文本编辑器中的html元素和其他元素
https://blog.csdn.net/fjssharpsword/article/details/53467079 1.应用场景:从一份html文件中或从String(是html内容)中提取纯文 ...
- 对于富文本编辑器中使用lazyload图片懒加载
使用lazyload.js图片懒加载的作用是给用户一个好的浏览体验,同时对服务器减轻了压力,当用户浏览到该图片的时候再对图片进行加载,项目中使用lazyload的时候需要将图片加入data-orgin ...
- 富文本编辑器直接从 word 中复制粘贴公式
在之前在工作中遇到在富文本编辑器中粘贴图片不能展示的问题,于是各种网上扒拉,终于找到解决方案,在这里感谢一下知乎中众大神以及TheViper. 通过知乎提供的思路找到粘贴的原理,通过TheViper找 ...
- 对于MVC中应用百度富文本编辑器问题的解决办法
1.对于应用富文本编辑器post提交表单内容提示有危险的解决办法: [ValidateInput(false)] //文本编辑器的表单提交不用提示危险 [HttpPost] public Action ...
- wangEditor-基于javascript和css开发的 Web富文本编辑器, 轻量、简洁、易用、开源免费(2)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- ssm项目中ueditor富文本编辑器的使用
一.下载 https://ueditor.baidu.com/website/index.html 将ueditor放到项目中合适的位置 二 . 配置文件上传路径 在utf8-jsp/jsp/conf ...
- 富文本编辑器实现从word中复制图片(外挂)
1问题 基于web的富文本编辑器的功能普遍较弱,而word是公认的宇宙第一好用的文档编辑器,所以许多人都习惯先在word中编辑,然后再将内容粘到web富文本编辑器中. 但是,这种操作有一个问题:图片带 ...
随机推荐
- nginx一致性hash及应用场景。
考虑一种场景. 多台web服务. 1 后台添加用户,更新用户信息,要求管理员能够实时看到变化. 2 前台用户允许1分钟后生效. nginx 配置一致性hash1. https://github.com ...
- Installing Ubuntu on a Pre-Installed Windows 8 (64-bit) System (UEFI Supported)
http://askubuntu.com/questions/221835/installing-ubuntu-on-a-pre-installed-windows-8-64-bit-system-u ...
- kvm usb2.0
Virt-Manager adds support for usb2 Wednesday, April 4, 2012 - 10:40 Haydn Solomon The most recent re ...
- JAVA中list,set,数组之间的转换详解
JAVA的list,set,数组之间的转换,主要是使用Apache Jakarta Commons Collections,具体的方法如下:import org.apache.commons.coll ...
- 跟我一步一步开发自己的Openfire插件
http://www.blogjava.net/hoojo/archive/2013/03/07/396146.html 跟我一步一步开发自己的Openfire插件 这篇是简单插件开发,下篇聊天记录插 ...
- IO负载高的来源定位 IO系列
http://elf8848.iteye.com/category/281637 前言: 在一般运维工作中经常会遇到这么一个场景,服务器的IO负载很高(iostat中的util),但是无法快速的定位到 ...
- WPF自定义窗体仿新毒霸关闭特效(只能在自定义窗体中正常使用)
比较简单的一个小功能,和新毒霸类似的效果. 效果代码: bool closeStoryBoardCompleted = false; DoubleAnimation closeAnimation1; ...
- iOS 开发中的争议(二)
这是该系列的第二篇.在本文中,我想讨论的是:对于 UI 界面的编写工作,到底应该用 xib/storyboard 完成,还是用手写代码来完成? 本着 “使用过才有发言权” 原则,我介绍一下我的经历: ...
- linux bash下 快捷键
c + a # 光标跳转到最左 c + e # 光标跳转到最后 c + w # 删除最后输入的单词 c + u # 删除整行 c + k # 删除光标到末尾 c + l # 清屏 c + z # 挂起 ...
- CentOS Linux修改系统时区
ln –sf /usr/share/zoneinfo/Hongkong /etc/localtime