构建你自己的JavaScript编辑器

分享于 

8分钟阅读

Web开发

  繁體 雙語

介绍

几个月前,我有一个情况,我需要构建自己的编辑器,将接受某些标签和属性。 我认为分享我的编辑器在浏览器独立的方式下是非常有趣的。 要查看演示,请在这里单击

使用代码

我想到的第一件事就是,我的设计师。IFramediv 或者什么是我的设计器的容器。 然后我决定将它设置为 div,然后将它的contentEditable属性设置为 true。

第二件事是,现在我的div 可以在设计时编辑,如何将标签应用于选定内容。 below 你将找到一个我构建的实用程序库,它有我们需要构建编辑器的基本方法。 在下一部分中,我将展示并解释 Editor 类。 现在,让我们从实用程序库中的重要方法开始。

// This function is used to get the selected Range.GetSelectedRange : function(controlContent){var selectedRange = null;if(document.selection)
 selectedRange = document.selection.createRange();elseif(window.selection)
 selectedRange = window.selection.createRange();if(selectedRange == null){
 if(window.getSelection()!= null)
 {
 if (this.Exists(window.getSelection().getRangeAt))
 selectedRange = window.getSelection().getRangeAt(0);
 else { // Safari!var range = document.createRange();
 range.setStart(window.getSelection().anchorNode,
 window.getSelection().anchorOffset);
 range.setEnd(window.getSelection().focusNode,
 window.getSelection().focusOffset);
 selectedRange = range;
 } 
 }
}var t = null; if(selectedRange!= null && this.BrowserType.IE)
{
 t = this.CheckParentById(controlContent.id,selectedRange.parentElement());
}else{
 t = this.RangeCompareNode(selectedRange,controlContent);
}if(!t && controlContent!= null)
 selectedRange = null;
 return selectedRange;
} 

上面 代码以浏览器独立方式获取选定的区域对象,以便在编辑器后面处理它。 然后它检查选中的范围是否在我们的编辑器 div 范围内。 如果不是,则返回 null 否则返回范围。 这里我们检查这个范围是否在父节点内,或者不是 IE 之外的浏览器。

// This function is used to get if the selected range in the//required parent in firefox. RangeCompareNode : function(range,node){
 var nodeRange = node.ownerDocument.createRange();
 try {
 nodeRange.selectNode(node);
 }
 catch (e) {
 nodeRange.selectNodeContents(node);
 }
 var nodeIsBefore =
 range.compareBoundaryPoints(Range.START_TO_START, nodeRange) == 1;
 var nodeIsAfter = range.compareBoundaryPoints(Range.END_TO_END, nodeRange) == -1;
 if (nodeIsBefore &&!nodeIsAfter)
 returnfalse;
 if (!nodeIsBefore && nodeIsAfter)
 returnfalse;
 if (nodeIsBefore && nodeIsAfter)
 returntrue;
 returnfalse;
 }

这里我们检查范围是否在父节点内,或者是否在 IE 浏览器中:

// This function is used to Check whether a parent element// contains the child element or not using the parentId. CheckParentById : function(parentId,child){
 while(child!= null){
 if(child.id == parentId) returntrue;
 child = child.parentNode;
 }
 returnfalse;
 }

基本上,编辑器被初始化为 inside RBMEditor 命名空间。 我将在编辑器中介绍一些重要的方法。 Execute命令方法首先获取当前选定范围,然后从范围中提取 HTML。 之后,它检查效果是否已经应用或者不是,如果是,它将使用 ExecuteUndoCommand 方法去除效果。 如果没有应用效果,那么我们从命令中创建一个新元素。 然后 SetHTMLFromSelection 方法将用选定的HTML中的新命令元素替换当前选定的区域。

ExecuteCommand: function(sCommand,id,value,name,isControl){
 var selection = RBM.GetSelectedRange(this.controlContent);
 if(selection == null)
 return;
 var html = this.GetHTMLFromSelection(selection);
 var undo = this.ExecuteUndoCommand(sCommand,new String(html));
 if(!undo){
 var element = this.CreateNewNode(sCommand,id,value,html);
 if(element!= null)
 this.SetHTMLFromSelection(selection,element);
 }
 }

GET 方法将解析HTML和代码,并从HTML代码中移除不支持的标记和属性。

GetHTML: function(sCode){
 //return sCode;var ts = new String(sCode);
 var parts = ts.split("<");
 var subpart = '';
 var i = 0;
 var j = 0;
 var totalStr = '';
 var tagName = '';
 var readTag = true;
 var readSub = true;
 for(i = 0; i <parts.length;i++)
 {
 if(parts[i] == '')
 continue;
 subpart = '';
 tagName = '';
 readTag = true;
 readSub = true;
 for(j = 0; j <parts[i].length; j++)
 {
 if(parts[i].substr(j,1) == '>')
 readSub = false;
 if(parts[i].substr(j,1) == ' ' || parts[i].substr(j,1) == '>')
 readTag = false;
 if(readSub == true)
 subpart = subpart + parts[i].substr(j,1);
 if(readTag == true)
 tagName = tagName + parts[i].substr(j,1);
 }
 if(this.IsSupportedTag(tagName) == false)
 {
 parts[i] = parts[i].replace(subpart + '>',' ');
 parts[i] = parts[i].replace('/' + tagName + '>',' ');
 }
 else {
 parts[i] = '<' + parts[i];
 parts[i] = this.RemoveUnknownAttributes
 (subpart.replace(tagName,''),parts[i]);
 }
 }
 var retValue = '';
 for(i = 0; i <parts.length;i++)
 {
 if(parts[i]!= '')
 retValue = retValue + parts[i];
 }
 var tnewValue = new String(retValue);
 return tnewValue;
 }

那么如何使用编辑器。 首先,你需要从类添加一个对象,并给它提供要作为编辑器的div id,但是要初始化它,你需要将它放在下面:

var editor;
 RBM.AddListener(window,'load',RbmInit);
 function RbmInit(){
 editor = new RBMEditor.Editor('oDiv')
 }

现在调用命令键入以下命令,可以在 EditorCommands 中发现的任何命令中更改粗体命令。

editor.ExecuteCommand(RBMEditor.EditorCommands.BOLD); 

finally 希望这篇文章能帮助你开始构建你自己的编辑器。 请问我是否有关于更高级技术或者如何添加链接,图片,等等,以及如何增强编辑的问题。

历史记录

  • 第 25th 2009年03月: 初始帖子

JAVA  Javascript  构建  EDI  Building