Example
This page is an example. Click on a paragraph, edit it, then click Ready. Your changes will appear.
Problem
The first problem I encountered is: I want to use the text box as the editing area. At first, I couldn't put the content into the text box. Readers discovered a warning from Mozilla that the value of a text box cannot be set until it is placed in the document.
In addition, the content packaging under Mozilla is not very good. I tried several wrap parameters, but the results were not very good.
The most serious problem is to send the modified content back to the server, which is what almost all CMS systems have to do. Readers have given me a lot of clever advice. However, since it can't be done via JavaScript, I can't provide a solution. So please don't send me an email saying you've found a way: that might work, but I just want a pure JavaScript way that doesn't require server-side code.
Script
var editing = false;
if (document.getElementById && document.createElement) {
var butt = document.createElement('BUTTON');
var buttext = document.createTextNode('Ready!');
butt.appendChild(buttext);
butt.onclick = saveEdit;
}
function catchIt(e) {
if (editing) return;
if (!document. getElementById || !document.createElement) return;
if (!e) var obj = window.event.srcElement;
else var obj = e.target;
while (obj.nodeType != 1) {
obj = obj.parentNode;
}
if (obj.tagName == 'TEXTAREA' || obj.tagName == 'A') return;
while (obj.nodeName != 'P' && obj.nodeName != 'HTML') {
obj = obj.parentNode;
}
if (obj.nodeName == 'HTML') return;
var x = obj .innerHTML;
var y = document.createElement('TEXTAREA');
var z = obj.parentNode;
z.insertBefore(y,obj);
z.insertBefore(butt,obj );
z.removeChild(obj);
y.value = x;
y.focus();
editing = true;
}
function saveEdit( ) {
var area = document.getElementsByTagName('TEXTAREA')[0];
var y = document.createElement('P');
var z = area.parentNode;
y. innerHTML = area.value;
z.insertBefore(y,area);
z.removeChild(area);
z.removeChild(document.getElementsByTagName('button')[0]);
Editing = false;
}
document.onclick = catchIt;
Explanation
We set an editing flag to false. This is used to show whether the user is editing a paragraph. Of course there is none initially.
var editing=false;
Create a button
Then we create a Radey button, which will be needed many times later. This requires some advanced scripting skills, so do some object detection first:
if (document.getElementById && document.createElement) {
If it’s a modern browser, create the button:
var butt = document.createElement('BUTTON');
His text is:
var buttext = document.createTextNode('Ready!');
Put this text Add to the button:
butt.appendChild(buttext);
Then add an onclick event handler:
butt .onclick = saveEdit; 2 }
Now the button is stored in the button, and we can reference it directly when needed.
Convert P to text box
Later we will define an onclick event for the entire page. All these events are sent to the catchIt() function.
function catchIt(e){
First check whether the user edits the paragraph normally. If so, end the function:
if (editing) return;
Then the support check:
if (!document.getElementById || !document.createElement) return;
Then look for the source of the event:
if (!e) var obj = window.event.srcElement; 2 else var obj = e.target;
Now we have the source of the event, but the problem is that Mozilla will think that the text node is the source (instead of the P node we need). So if the node is not a label (nodeType is not 1), we need to traverse the DOM tree upwards:
while (obj.nodeType != 1) { 2 obj = obj.parentNode; 3 }
Now we end with a label. If this is the label of a text box, the user can edit it after clicking on it. If it is a link label, it should still be reflected as a link after the user clicks it. In these two cases we do not need this function:
if (obj.tagName == 'TEXTAREA' || obj.tagName == 'A') return;
We need to traverse the DOM tree upward again until we find the P tag or HTML tag:
while (obj.nodeName != 'P' && obj.nodeName ! = 'HTML') { 2 obj = obj.parentNode; 3 }
If it is an HTML tag, it means that the user clicked outside the paragraph, and the function ends:
if (obj.nodeName == 'HTML') return;
After this detection we Finally, we make sure that the user clicks on the paragraph we want to edit. Then save the innerHTML of the paragraph:
var x = obj.innerHTML ;
Create a new TEXTAREA and save it:
var y = document.createElement('TEXTAREA');
Then find the parent node of the paragraph:
var z = obj.parentNode;
Now it looks like this:
z
|
---------------------------------------
| | | | |
[more] y(TEXTAREA) butt(BUTTON) P [more]
Copy after login
Then delete the paragraph. Now it looks like text boxes and buttons have replaced the previous paragraph.
Until now, after inserting the text box, we can place the innerHTML of the paragraph inside the text box. Mozilla does not support adding content to the text box before inserting.
y.value = x;
Copy after login
Give focus to the text box for user convenience:
y.focus();
Copy after login
Then set editing to true.
editing = true;
}
Copy after login
Convert the text box to P
When the user clicks the Ready button, it should be the other way around. This is done by the saveEdit() function.
function saveEdit() {Get TEXTAREA (assume here there is only one TEXTAREA in the entire page):
var area = document.getElementsByTagName('TEXTAREA')[0] Create a new paragraph and save:
var y = document.createElement('P');
Find the text The parent element of the box: the new paragraph needs to be added there:
var z = area.parentNode;
Store the value of the text box in a new paragraph:
y.innerHTML = area.value;
Then insert the new paragraph before the text box:
z.insertBefore(y,area);
Remove text box:
z.removeChild(area);
Remove the Ready button (Similarly, assuming the page has only one button ):
z.removeChild(document.getElementsByTagName('button')[ 0]);
Then set editing to false: the user stops editing:
editing = false; 2 }
Event
Outside the function, set an onclick event for the entire page:
document.onclick = catchIt;
Translation address: http://www.quirksmode.org/dom/cms.html
Please keep the following information when reprinting
Author: Beiyu (tw:@rehawk)