JavaScript Development Essay 3 A little experience in developing an IFrame Rich Text Editor _ Web page Editor

Source: Internet
Author: User
Tags tagname
Keep a record of the problems you have encountered. The TINYMCE editor used to write this article is powerful, but it's a third party, and the project takes that into account, and it's not convenient to do something customized.
1. Determine the style of the element (or selected part) of the cursor position. Updates the style of the toolbar's corresponding button when the cursor position changes. Under what circumstances will the cursor position change? Keyboard key and mouse click, so that the keyboard events and mouse events to perform cursor movement processing.
A. Get the cursor position or selected element: First getselection, create range. Then get the elements, get to the element can be or get style, tagname, etc., do more operations, run the code:
Copy Code code as follows:

<! DOCTYPE HTML PUBLIC "-//w3c//dtd HTML 4.01 transitional//en" >
<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>
<body>
<span style= "display:block;height:150px; font-size:12px;line-height:150% "> Information </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 Masaki
var css = Document.defaultview? function (El,style) {
Return Document.defaultView.getComputedStyle (EL, null). GetPropertyValue (Style)
}: Function (El,style) {
style = Style.replace (/\-(\w)/g, function ($, $) {
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: bold; Font-weight:bold; " > A four major four </span> big <span style= "font-style:italic; Text-decoration:underline; " > Four Big Four plans </span> dozen <span style= "font-style:italic; Color: #ff0000; > Doubles SARS </span> master ';
Ifr_doc.designmode= ' on ';//Editable
Ifr_doc.contenteditable = true;
Ifr_doc.open ();
Ifr_doc.writeln (' 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 ') + ' > font: ' + CSS (node, ' font-family ') + ' </span> <br/> ';
html+= ' <span style= ' color: ' + CSS (node, ' color ') + ' > Colors: ' + CSS (node, ' color ') + ' </span><br/> ';
html+= ' <span style= font-style: ' + CSS (node, ' font-style ') + ' > Italic: ' + CSS (node, ' font-style ') + ' </span>< br/> ';
html+= ' <span style= font-weight: ' + CSS (node, ' font-weight ') + ' > Bold: ' + CSS (node, ' font-weight ') + ' </span> <br/> ';
html+= ' <span style= text-decoration: ' + CSS (node, ' text-decoration ') + ' > Underline: ' + CSS (node, ' text-decoration ') + ' </span><br/> ';
html+= ' tagName: ' + node.tagname + ', style: ' + node.getattribute (' style ') + ' <br/> ';

info.innerhtml = html;
}
Executes when the cursor position changes
var onselectionchange = function (event) {
var e = Event | | window.event;
if (!e.keycode) E.keycode = E.which;
The arrow keys move the cursor to get the DOM of the cursor position
if ((E.keycode >= && e.keycode <=) | | e.type = = "click") {

var node = GetRange (). node;//get the cursor position element
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>

2. IE can not keep the cursor position, this is the problem when adding hyperlinks, when not using the browser built in the input box, the cursor moves other text fields, IE will lose the selected part, can not select the part of the link, The solution is to use range GetBookmark and MoveToBookmark, and then bind the document of the IFRAME to Onbeforedeactivate (GetBookmark), OnActivate (MoveTo), the general meaning of these 2 events is that when activated and deactivated. After adding an event, you don't have to save the Lastrang or set up a bookmark anywhere else, so IE keeps the cursor position automatically like any other browser.
Copy Code code as follows:

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 in the undo and redo. When a pop-up window is outside the IFRAME, or modify the HTML undo, redo function will be invalidated. Can only be classified as IE bug .... Perhaps IE did not distinguish the IFRAME and page document, their undo, redo the moral of the mix.
As follows:
Copy Code code as follows:

<! DOCTYPE HTML PUBLIC "-//w3c//dtd HTML 4.01 transitional//en" >
<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>
<body>
<span style= "display:block;height:150px; font-size:12px;line-height:150% "> Information </span>
<div id= "J_tool" >
<input type= "button" command= "undo" value= "Undo" unselectable= "on"/>
<input type= "button" command= "Redo" value= "Redo" unselectable= "on"/>
<input type= "button" command= "bold" value= "bold" unselectable= "on"/>
<input type= "button" command= "italic" value= "italic" unselectable= "on"/>
</div>
<br/>
<input type= "button" onclick= "Changelayout ()" value= "click, ie will not undo, redo"/>
<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;p osition:absolute;left:0;top : 0px;text-align:center;line-height:150px; ';
popwin.innerhtml = ' changed layoud rendering, IE will not undo, Redo ';
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 Masaki
var css = Document.defaultview? function (El,style) {
Return Document.defaultView.getComputedStyle (EL, null). GetPropertyValue (Style)
}: Function (El,style) {
style = Style.replace (/\-(\w)/g, function ($, $) {
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: bold; Font-weight:bold; " > A four major four </span> big <span style= "font-style:italic; Text-decoration:underline; " > Four Big Four plans </span> dozen <span style= "font-style:italic; Color: #ff0000; > Doubles SARS </span> master ';
Ifr_doc.designmode= ' on ';//Editable
Ifr_doc.contenteditable = true;
Ifr_doc.open ();
Ifr_doc.writeln (' 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 ') + ' > font: ' + CSS (node, ' font-family ') + ' </span> <br/> ';
html+= ' <span style= ' color: ' + CSS (node, ' color ') + ' > Colors: ' + CSS (node, ' color ') + ' </span><br/> ';
html+= ' <span style= font-style: ' + CSS (node, ' font-style ') + ' > Italic: ' + CSS (node, ' font-style ') + ' </span>< br/> ';
html+= ' <span style= font-weight: ' + CSS (node, ' font-weight ') + ' > Bold: ' + CSS (node, ' font-weight ') + ' </span> <br/> ';
html+= ' <span style= text-decoration: ' + CSS (node, ' text-decoration ') + ' > Underline: ' + CSS (node, ' text-decoration ') + ' </span><br/> ';
html+= ' tagName: ' + node.tagname + ', style: ' + node.getattribute (' style ') + ' <br/> ';
info.innerhtml = html;
}
Executes when the cursor position changes
var onselectionchange = function (event) {
var e = Event | | window.event;
if (!e.keycode) E.keycode = E.which;
The arrow keys move the cursor to get the DOM of the cursor position
if ((E.keycode >= && e.keycode <=) | | e.type = = "click") {
var node = GetRange (). node;//get the cursor position element
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>

How to solve it? You can only rely on JavaScript to simulate undo and redo. There are still a lot of resources in this area of the network, so it is not explained in detail
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.