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