首页前端开发其他前端知识javascript开发随笔3 开发iframe富文本编辑器的一点体会

javascript开发随笔3 开发iframe富文本编辑器的一点体会

时间2024-02-10 11:44:03发布访客分类其他前端知识浏览420
导读:收集整理的这篇文章主要介绍了javascript开发随笔3 开发iframe富文本编辑器的一点体会,觉得挺不错的,现在分享给大家,也给大家做个参考。 就把遇到的问题记录一下。写这篇文章时...
收集整理的这篇文章主要介绍了javascript开发随笔3 开发iframe富文本编辑器的一点体会,觉得挺不错的,现在分享给大家,也给大家做个参考。 就把遇到的问题记录一下。写这篇文章时用的TinyMCE编辑器就很强大,但毕竟是第三方的,项目也考虑了这些,如果做些自定义的东西不太方便。
1. 判断光标位置的元素(或者选中的部分)的样式。光标位置改变的时候更新工具栏对应按钮的样式。什么情况下光标的位置会改变呢?是键盘方向键和鼠标点击,于是就判断键盘事件和鼠标事件来执行光标移动的处理。
a. 获得光标位置或选中元素:首先getSelection,创建range。然后获得元素,获取到元素之后就可以或得样式、tagName等等,做更多的操作,运行代码:
复制代码 代码如下:
!DOCTYPE HTML PubLIC "-//W3C//DTD HTML 4.01 TransITional//EN">
html>
head>
title> /title>
meta http-equiv="Content-type" content="text/html; charset=UTF-8">
style type="text/css">
p{ width:600px; text-align: left; text-indent:2em; line-height:20px; font-Size:12px}
textarea{ width:600px; height:100px; font-size:12px; overflow:auto}
/style>
/head>
body>
span style="display:block; height:150px; font-size:12px; line-height:150%"> 信息/span>
script type="text/javascript">
function createEditor(){
VAR iframe = document.createElement('iframe');
iframe.id = 'iframe';
iframe.frameBorder = 1;
iframe.width = 400;
iframe.height = 200;
document.body.appendChild(iframe);
return iframe;
}
var bind = function(element,eventType,fn,useCapture){
useCapture = useCapture || false;
if(arguments.length 3){
return true
} ;
if(window.addEventListener){
element.addEventListener(eventType, fn, useCapture);
} else{
element.attachEvent('on'+eventType,fn, useCapture);
}
}
//From 司徒正美
var css = document.defaultView ? function(el,style){
return document.defaultView.getComputedStyle(el, null).getPRopertyValue(style)
} : function(el,style){
style = style.replace(/\-(\w)/g, function($, $1){
return $1.toUpperCase();
} );
return el.currentStyle[style];
}
function bindEditor(){
var iframe = createEditor();
var ifr_win = iframe.contentWindow;
var ifr_doc = ifr_win.document;

var editorContent = 'span style="font-family: 黑体; font-weight: bold; "> 阿四大四大四/span> 大span style="font-style: italic; text-decoration: underline; "> 四大四大打算/span> 打打span style="font-style: italic; color: #ff0000; "> 双打萨斯/span> 大师';
ifr_doc.designMode='On'; //可编辑
ifr_doc.contentEditable = true;
ifr_doc.open();
ifr_doc.writeln('html> head> style type="text/css"> body{ padding:10px; margin:0; font-size:13px; font-family:宋体; text-align:left; overflow:auto; word-wrap: break-word; cursor:text; background-color: transparent; } body,p,font,div,ul,li { line-height: 1.5; } p,font,div,ul,li { line-height: 1.5; margin:0; padding:0} a{ color:#548DD4} /style> /head> body> '+ editorContent +'/body> /html> ');
ifr_doc.close();

var getRange = function(){
var range = window.getSelection ? ifr_win.getSelection() : ifr_win.document.selection;
if (!range) {
return {
node : null,
range : null,
text : null
} ;
}
range = range.createRange ? range.createRange() : range.getRangeAt(0);
var text = window.getSelection ? range : range.text;
var rangeNode = null;
if (range.COMmonAncestorContainer) {
rangeNode = range.commonAncestorContainer;
} else {
if (range.parentElement) rangeNode = range.parentElement();
}
return {
node : rangeNode,
range : range,
text : text
}
}
var info = document.getelementsbytagname('span')[0];
var getStyle = function(node){
//console.LOG(node)
var html = '';
html+= 'span style="font-family:'+ css(node,'font-family') +'"> 字体:'+ css(node,'font-family') + '/span> br /> ';
html+= 'span style="color:'+ css(node,'color') +'"> 颜色:'+ css(node,'color') + '/span> br /> ';
html+= 'span style="font-style:'+ css(node,'font-style') +'"> 斜体:'+ css(node,'font-style') + '/span> br /> ';
html+= 'span style="font-weight:'+ css(node,'font-weight') +'"> 粗体:'+ css(node,'font-weight') + '/span> br /> ';
html+= 'span style="text-decoration:'+ css(node,'text-decoration') +'"> 下划线:'+ css(node,'text-decoration') + '/span> br /> ';
html+= 'tagName:'+ node.tagName + ',style:'+ node.getAttribute('style') +'br /> ';

info.innerHTML = html;
}
//当光标位置改变时候执行
var onselectionchange = function(event){
var e = event || window.event;
if(!e.keyCode)e.keyCode = e.which;
//方向键移动光标,获取光标位置的dom
if((e.keyCode > = 37 & & e.keyCode = 40 )|| e.type == "click"){

var node = getRange().node; //获取光标位置元素
if(node !== null){
while(node.nodeType != 1){
node = node.parentNode;
}
getStyle(node);
}
}
}

bind(ifr_doc,'click',onselectionchange,false);
bind(ifr_doc,'keydown',onselectionchange,false);
}
window.onload = function(){
bindEditor();
}
/script>
/body>
/html>

2. ie不能保持光标位置,这个是在添加超链接时候出现的问题,当不使用浏览器内置的输入框,光标移动其他的文本域里,ie会失去所选中的部分,无法对选中的部分加链接了,解决办法就是:利用range的getBookmark和moveToBookmark,然后给iframe的document绑定onbeforedeactivate(getBookmark)、onactivate(moveTo),这2个事件的大致意思就是,当被激活和失去激活状态。增加事件之后,就不必保存lastRang或者再其他地方设置bookmark了,可以让ie像其他浏览器一样自动保持光标位置了
复制代码 代码如下:
if(Util.browser.msie){
Util.bind(this.E.ifr_win.document, "beforedeactivate", function(){
var Rng = _self.getRange().range;
_self.rangeBookMark= Rng.getBookmark();
} );
Util.bind(this.E.ifr_win.document, "activate", function(){
var Rng = _self.getRange().range;
Rng.moveToBookmark(_self.rangeBookMark);
Rng.select();
_self.rangeBookMark = null;
} );
}

3. ie中的撤销与重做 。 当iframe外部有弹出窗口、或者修改html撤销、重做功能将失效。只能归为ie的bug了。。。。也许ie没分清iframe和页面的document,把他们的撤销、重做混道义了。
如下:
复制代码 代码如下:
!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
html>
head>
title> /title>
meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
style type="text/css">
p{ width:600px; text-align: left; text-indent:2em; line-height:20px; font-size:12px}
textarea{ width:600px; height:100px; font-size:12px; overflow:auto}
/style>
/head>
body>
span style="display:block; height:150px; font-size:12px; line-height:150%"> 信息/span>
div id="J_tool">
input type="button" command="Undo" value="撤销" unselectable="on" />
input type="button" command="Redo" value="重做" unselectable="on" />
input type="button" command="Bold" value="粗体" unselectable="on" />
input type="button" command="Italic" value="斜体" unselectable="on" />
/div>
br />
input type="button" onclick="changeLayout()" value="点击下,ie将无法撤销、重做" />
br />
script type="text/javascript">
function changeLayout(){
var popwin = document.getElementById('popwin');
if(!popwin){
popwin = document.createElement('div');
popwin.id = 'popwin';
popwin.style.cssText = 'display:none; width:300px; height:150px; background-color:#ccc; position:absolute; left:0; top:0px; text-align:center; line-height:150px; ';
popwin.innerHTML = '改变了layoud渲染,ie将无法撤销、重做';
document.body.appendChild(popwin);
popwin.onclick= function(){ this.style.display = 'none'} ;
}
popwin.style.display = popwin.style.display == 'none' ? 'block' : 'none';
}
function createEditor(){
var iframe = document.createElement('iframe');
iframe.id = 'iframe';
iframe.frameBorder = 1;
iframe.width = 400;
iframe.height = 200;
document.body.appendChild(iframe);
return iframe;
}
var bind = function(element,eventType,fn,useCapture){
useCapture = useCapture || false;
if(arguments.length 3){
return true
} ;
if(window.addEventListener){
element.addEventListener(eventType, fn, useCapture);
} else{
element.attachEvent('on'+eventType,fn, useCapture);
}
}
//from 司徒正美
var css = document.defaultView ? function(el,style){
return document.defaultView.getComputedStyle(el, null).getPropertyValue(style)
} : function(el,style){
style = style.replace(/\-(\w)/g, function($, $1){
return $1.toUpperCase();
} );
return el.currentStyle[style];
}
function bindEditor(){
var iframe = createEditor();
var ifr_win = iframe.contentWindow;
var ifr_doc = ifr_win.document;
var editorContent = 'span style="font-family: 黑体; font-weight: bold; "> 阿四大四大四/span> 大span style="font-style: italic; text-decoration: underline; "> 四大四大打算/span> 打打span style="font-style: italic; color: #ff0000; "> 双打萨斯/span> 大师';
ifr_doc.designMode='On'; //可编辑
ifr_doc.contentEditable = true;
ifr_doc.open();
ifr_doc.writeln('html> head> style type="text/css"> body{ padding:10px; margin:0; font-size:13px; font-family:宋体; text-align:left; overflow:auto; word-wrap: break-word; cursor:text; background-color: transparent; } body,p,font,div,ul,li { line-height: 1.5; } p,font,div,ul,li { line-height: 1.5; margin:0; padding:0} a{ color:#548DD4} /style> /head> body> '+ editorContent +'/body> /html> ');
ifr_doc.close();
var getRange = function(){
var range = window.getSelection ? ifr_win.getSelection() : ifr_win.document.selection;
if (!range) {
return {
node : null,
range : null,
text : null
} ;
}
range = range.createRange ? range.createRange() : range.getRangeAt(0);
var text = window.getSelection ? range : range.text;
var rangeNode = null;
if (range.commonAncestorContainer) {
rangeNode = range.commonAncestorContainer;
} else {
if (range.parentElement) rangeNode = range.parentElement();
}
return {
node : rangeNode,
range : range,
text : text
}
}
var info = document.getElementsByTagName('span')[0];
var getStyle = function(node){
//console.log(node)
var html = '';
html+= 'span style="font-family:'+ css(node,'font-family') +'"> 字体:'+ css(node,'font-family') + '/span> br /> ';
html+= 'span style="color:'+ css(node,'color') +'"> 颜色:'+ css(node,'color') + '/span> br /> ';
html+= 'span style="font-style:'+ css(node,'font-style') +'"> 斜体:'+ css(node,'font-style') + '/span> br /> ';
html+= 'span style="font-weight:'+ css(node,'font-weight') +'"> 粗体:'+ css(node,'font-weight') + '/span> br /> ';
html+= 'span style="text-decoration:'+ css(node,'text-decoration') +'"> 下划线:'+ css(node,'text-decoration') + '/span> br /> ';
html+= 'tagName:'+ node.tagName + ',style:'+ node.getAttribute('style') +'br /> ';
info.innerHTML = html;
}
//当光标位置改变时候执行
var onselectionchange = function(event){
var e = event || window.event;
if(!e.keyCode)e.keyCode = e.which;
//方向键移动光标,获取光标位置的dom
if((e.keyCode > = 37 & & e.keyCode = 40 )|| e.type == "click"){
var node = getRange().node; //获取光标位置元素
if(node !== null){
while(node.nodeType != 1){
node = node.parentNode;
}
getStyle(node);
}
}
}
bind(ifr_doc,'click',onselectionchange,false);
bind(ifr_doc,'keydown',onselectionchange,false);
bind(document.getElementById('J_tool'),'click',function(event){
event = event || window.event;
var target = event.srcElement || event.target;
var command = target.getAttribute('command');
var param = target.getAttribute('param') || '';
ifr_doc.execCommand(command,false,param);
return false;
} )
}
window.onload = function(){
bindEditor();
}
/script>
/body>
/html>

如何解决呢? 只能依靠javascript模拟撤销与重做了。网络这方面的资源还是不少的,就不在此详细说明了
您可能感兴趣的文章:
  • nodejs后台集成ueditor富文本编辑器的实例@H_856_304@
  • Vue.js结合Ueditor富文本编辑器的实例代码
  • Javascript实现简单的富文本编辑器附演示
  • 学习js在线html(富文本,所见即所得)编辑器
  • 19款Javascript富文本网页编辑器
  • 不到200行 JavaScript 代码实现富文本编辑器的方法

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!


若转载请注明出处: javascript开发随笔3 开发iframe富文本编辑器的一点体会
本文地址: https://pptw.com/jishu/608315.html
PHP中CKEditor和CKFinder配置问题小结 FCKeditor 2.6.6在ASP中的安装及配置方法分享

游客 回复需填写必要信息