2个好用的js(实现树型菜单&&页面中展现word)

来源:互联网 发布:淘宝摄影服务商 编辑:程序博客网 时间:2024/05/29 13:33

1.editor.js

 

// <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
//
 需要IE5.5以上的版本支持


// write out styles for UI buttons
document.write('<style type="text/css"> ');
document.write(
'.btn     { width: 22px; height: 22px; border: 1px solid buttonface; margin: 0; padding: 0; } ');
document.write(
'.btnOver { width: 22px; height: 22px; border: 1px outset; } ');
document.write(
'.btnDown { width: 22px; height: 22px; border: 1px inset; background-color: buttonhighlight; } ');
document.write(
'.btnNA   { width: 22px; height: 22px; border: 1px solid buttonface; filter: alpha(opacity=25); } ');
document.write(
'.cMenu     { background-color: threedface; color: menutext; cursor: Default; font-family: MS Sans Serif; font-size: 8pt; padding: 2 12 2 16; }');
document.write(
'.cMenuOver { background-color: highlight; color: highlighttext; cursor: Default; font-family: MS Sans Serif; font-size: 8pt; padding: 2 12 2 16; }');
document.write(
'.cMenuDivOuter { background-color: threedface; height: 9 }');
document.write(
'.cMenuDivInner { margin: 0 4 0 4; border-width: 1; border-style: solid; border-color: threedshadow threedhighlight threedhighlight threedshadow; }');
document.write(
'</style> ');


/* ---------------------------------------------------------------------- *
  Function    : editor_defaultConfig 系统默认的模式
  Description : default configuration settings for wysiwyg editor
* ---------------------------------------------------------------------- 
*/


function editor_defaultConfig(objname) {

    
this.version = "2.03"

    
this.width =  "auto";
    
this.height = "auto";
    
this.bodyStyle = 'background-color: #FFFFFF; font-family: "Verdana"; font-size: x-small;';
    
this.imgURL = _editor_url + 'images/';
    
this.debug  = 0;

    
this.replaceNextlines = 0// replace nextlines from spaces (on output)
    this.plaintextInput = 0;   // replace nextlines with breaks (on input)

    
this.toolbar = [
                    [
'fontname'],
                    [
'fontsize'],
                
//    ['fontstyle'],
                //    ['linebreak'],
                    ['bold','italic','underline','separator'],
                
//  ['strikethrough','subscript','superscript','separator'],
                    ['justifyleft','justifycenter','justifyright','separator'],
                    [
'OrderedList','UnOrderedList','Outdent','Indent','separator'],
                    [
'forecolor','backcolor','separator'],
                    [
'HorizontalRule','Createlink','InsertImage','InsertTable','htmlmode','separator'],
                
//  ['custom1','custom2','custom3','separator'],
                    ['popupeditor','about']
        ];

    
this.fontnames = {
                    
"Arial":           "arial, helvetica, sans-serif",
                    
"Courier New":     "courier new, courier, mono",
                    
"Georgia":         "Georgia, Times New Roman, Times, Serif",
                    
"Tahoma":          "Tahoma, Arial, Helvetica, sans-serif",
                    
"Times New Roman""times new roman, times, serif",
                    
"Verdana":         "Verdana, Arial, Helvetica, sans-serif",
                    
"impact":          "impact",
                    
"WingDings":       "WingDings"
        }
;

    
this.fontsizes = {
            
"1 (8 pt)":  "1",
            
"2 (10 pt)""2",
            
"3 (12 pt)""3",
            
"4 (14 pt)""4",
            
"5 (18 pt)""5",
            
"6 (24 pt)""6",
            
"7 (36 pt)""7"
      }
;

////    this.stylesheet = "http://www.domain.com/sample.css"; // full URL to stylesheet

    
this.fontstyles = [     // make sure these exist in the header of page the content is being display as well in or they won't work!
    //    { name: "headline",     className: "headline",  classStyle: "font-family: arial black, arial; font-size: 28px; letter-spacing: -2px;" },
    //    { name: "arial red",    className: "headline2", classStyle: "font-family: arial black, arial; font-size: 12px; letter-spacing: -2px; color:red" },
    //    { name: "verdana blue", className: "headline4", classStyle: "font-family: verdana; font-size: 18px; letter-spacing: -2px; color:blue" },
    ];

    
this.btnList = {
            
// buttonName:    commandID,               title,                onclick,                   image,
            "bold":           ['Bold',                 '加粗',               'editor_action(this.id)',  'ed_format_bold.gif'],
            
"italic":         ['Italic',               '斜体',             'editor_action(this.id)',  'ed_format_italic.gif'],
            
"underline":      ['Underline',            'Underline',          'editor_action(this.id)',  'ed_format_underline.gif'],
            
"strikethrough":  ['StrikeThrough',        'Strikethrough',      'editor_action(this.id)',  'ed_format_strike.gif'],
            
"subscript":      ['SubScript',            'Subscript',          'editor_action(this.id)',  'ed_format_sub.gif'],
            
"superscript":    ['SuperScript',          'Superscript',        'editor_action(this.id)',  'ed_format_sup.gif'],
            
"justifyleft":    ['JustifyLeft',          'Justify Left',       'editor_action(this.id)',  'ed_align_left.gif'],
            
"justifycenter":  ['JustifyCenter',        'Justify Center',     'editor_action(this.id)',  'ed_align_center.gif'],
            
"justifyright":   ['JustifyRight',         'Justify Right',      'editor_action(this.id)',  'ed_align_right.gif'],
            
"orderedlist":    ['InsertOrderedList',    'Ordered List',       'editor_action(this.id)',  'ed_list_num.gif'],
            
"unorderedlist":  ['InsertUnorderedList',  'Bulleted List',      'editor_action(this.id)',  'ed_list_bullet.gif'],
            
"outdent":        ['Outdent',              'Decrease Indent',    'editor_action(this.id)',  'ed_indent_less.gif'],
            
"indent":         ['Indent',               'Increase Indent',    'editor_action(this.id)',  'ed_indent_more.gif'],
            
"forecolor":      ['ForeColor',            'Font Color',         'editor_action(this.id)',  'ed_color_fg.gif'],
            
"backcolor":      ['BackColor',            'Background Color',   'editor_action(this.id)',  'ed_color_bg.gif'],
            
"horizontalrule": ['InsertHorizontalRule''Horizontal Rule',    'editor_action(this.id)',  'ed_hr.gif'],
            
"createlink":     ['CreateLink',           'Insert Web Link',    'editor_action(this.id)',  'ed_link.gif'],
            
"insertimage":    ['InsertImage',          'Insert Image',       'editor_action(this.id)',  'ed_image.gif'],
            
"inserttable":    ['InsertTable',          'Insert Table',       'editor_action(this.id)',  'insert_table.gif'],
            
"htmlmode":       ['HtmlMode',             'View HTML Source',   'editor_setmode(''+objname+'')''ed_html.gif'],
            
"popupeditor":    ['popupeditor',          'Enlarge Editor',     'editor_action(this.id)',  'fullscreen_maximize.gif'],
            
"about":          ['about',                '关于当前编辑器',  'editor_about(''+objname+'')',  'ed_about.gif'],

            
// Add custom buttons here:
            "custom1":           ['custom1',         'Purpose of button 1',  'editor_action(this.id)',  'ed_custom.gif'],
            
"custom2":           ['custom2',         'Purpose of button 2',  'editor_action(this.id)',  'ed_custom.gif'],
            
"custom3":           ['custom3',         'Purpose of button 3',  'editor_action(this.id)',  'ed_custom.gif'],
           
// end: custom buttons

            
"help":           ['showhelp',             'Help using editor',  'editor_action(this.id)',  'ed_help.gif']
        }
;


}



/* ---------------------------------------------------------------------- *
  Function    : editor_generate 设置编辑器的对象和内容
  Description : replace textarea with wysiwyg editor
  Usage       : editor_generate("textarea_id",[height],[width]);
  Arguments   : objname - ID of textarea to replace
                w       - width of wysiwyg editor
                h       - height of wysiwyg editor
* ---------------------------------------------------------------------- 
*/



function editor_generate(objname,userConfig) {

  
// Default Settings
  var config = new editor_defaultConfig(objname);
      
if (userConfig) {
        
for (var thisName in userConfig) {
              
if (userConfig[thisName]) {
                      config[thisName] 
= userConfig[thisName];
                }

        }

      }

  document.all[objname].config 
= config; // store config settings

  
// set size to specified size or size of original object
  var obj    = document.all[objname];
          
if (!config.width || config.width == "auto"{
                
if (obj.style.width) {   // use css style
                        config.width = obj.style.width;
                }
else if (obj.cols){  // col width + toolbar
                        config.width = (obj.cols * 8+ 22;
                }
else {  // default
                        config.width = '100%';
                }

          }


          
if (!config.height || config.height == "auto"{
                
if(obj.style.height){  // use css style
                        config.height = obj.style.height;
                }
else if (obj.rows){  // row height
                        config.height = obj.rows * 17
                }
else// default
                        config.height = '200';
                }

          }


  
var tblOpen  = '<table border=0 cellspacing=0 cellpadding=0 style="float: left;"  unselectable="on"><tr><td style="border: none; padding: 1 0 0 0"><nobr>';
  
var tblClose = '</nobr></td></tr></table> ';

  
// build button toolbar

  
var toolbar = '';
  
var btnGroup, btnItem, aboutEditor;
  
for (var btnGroup in config.toolbar) {

    
// linebreak
    if (config.toolbar[btnGroup].length == 1 &&
        config.toolbar[btnGroup][
0].toLowerCase() == "linebreak"{
      toolbar 
+= '<br clear="all">';
      
continue;
    }


    toolbar 
+= tblOpen;
    
for (var btnItem in config.toolbar[btnGroup]) {
      
var btnName = config.toolbar[btnGroup][btnItem].toLowerCase();

      
// fontname
      if (btnName == "fontname"{
        toolbar 
+= '<select id="_' +objname+ '_FontName" onChange="editor_action(this.id)" unselectable="on" style="margin: 1 2 0 2; font-size: 12px;">';
        
for (var fontname in config.fontnames) {
          toolbar 
+= '<option value="' +config.fontnames[fontname]+ '">' +fontname+ '</option>'
        }

        toolbar 
+= '</select>';
        
continue;
      }


      
// fontsize
      if (btnName == "fontsize"{
        toolbar 
+= '<select id="_' +objname+ '_FontSize" onChange="editor_action(this.id)" unselectable="on" style="margin: 1 2 0 0; font-size: 12px;">';
        
for (var fontsize in config.fontsizes) {
          toolbar 
+= '<option value="' +config.fontsizes[fontsize]+ '">' +fontsize+ '</option>'
        }

        toolbar 
+= '</select> ';
        
continue;
      }


      
// font style
      if (btnName == "fontstyle"{
        toolbar 
+= '<select id="_' +objname+ '_FontStyle" onChange="editor_action(this.id)" unselectable="on" style="margin: 1 2 0 0; font-size: 12px;">';
        
+ '<option value="">Font Style</option>';
        
for (var i in config.fontstyles) {
          
var fontstyle = config.fontstyles[i];
          toolbar 
+= '<option value="' +fontstyle.className+ '">' +fontstyle.name+ '</option>'
        }

        toolbar 
+= '</select>';
        
continue;
      }


      
// separator
      if (btnName == "separator"{
        toolbar 
+= '<span style="border: 1px inset; width: 1px; font-size: 16px; height: 16px; margin: 0 3 0 3"></span>';
        
continue;
      }


      
// buttons
      var btnObj = config.btnList[btnName];
      
if (btnName == 'linebreak'{ alert("htmlArea error: 'linebreak' must be in a subgroup by itself, not with other buttons. htmlArea wysiwyg editor not created."); return; }
      
if (!btnObj) { alert("htmlArea error: button '" +btnName+ "' not found in button list when creating the wysiwyg editor for '"+objname+"'. Please make sure you entered the button name correctly. htmlArea wysiwyg editor not created."); return; }
      
var btnCmdID   = btnObj[0];
      
var btnTitle   = btnObj[1];
      
var btnOnClick = btnObj[2];
      
var btnImage   = btnObj[3];
      toolbar 
+= '<button title="' +btnTitle+ '" id="_' +objname+ '_' +btnCmdID+ '" class="btn" onClick="' +btnOnClick+ '" onmouseover="if(this.className=='btn'){this.className='btnOver'}" onmouseout="if(this.className=='btnOver'){this.className='btn'}" unselectable="on"><img src="' +config.imgURL + btnImage+ '" border=0 unselectable="on"></button>';


    }
 // end of button sub-group
    toolbar += tblClose;
  }
 // end of entire button set

  
// build editor

  
var editor = '<span id="_editor_toolbar"><table border=0 cellspacing=0 cellpadding=0 bgcolor="buttonface" style="padding: 1 0 0 2" width=' + config.width + ' unselectable="on"><tr><td> '
  
+ toolbar
  
+ '</td></tr></table> '
  
+ '</td></tr></table></span> '
  
+ '<textarea ID="_' +objname + '_editor" style="width:' +config.width+ '; height:' +config.height+ '; margin-top: -1px; margin-bottom: -1px;" wrap=soft></textarea>';

  
// add context menu
  editor += '<div id="_' +objname + '_cMenu" style="position: absolute; visibility: hidden;"></div>';

  
//  hide original textarea and insert htmlarea after it
  if (!config.debug) { document.all[objname].style.display = "none"; }

  
if (config.plaintextInput) {     // replace nextlines with breaks
    var contents = document.all[objname].value;
    contents 
= contents.replace(/ /g, '<br>');
    contents 
= contents.replace(/ /g, '<br>');
    contents 
= contents.replace(/ /g, '<br>');
    document.all[objname].value 
= contents;
  }


  
// insert wysiwyg
  document.all[objname].insertAdjacentHTML('afterEnd', editor)

  
// convert htmlarea from textarea to wysiwyg editor
  editor_setmode(objname, 'init');

  
// call filterOutput when user submits form
  for (var idx=0; idx < document.forms.length; idx++{
    
var r = document.forms[idx].attachEvent('onsubmit'function() { editor_filterOutput(objname); });
    
if (!r) { alert("Error attaching event to form!"); }
  }


return true;

}


/* ---------------------------------------------------------------------- *
  Function    : editor_action
  Description : perform an editor command on selected editor content
  Usage       :
  Arguments   : button_id - button id string with editor and action name
* ---------------------------------------------------------------------- 
*/


function editor_action(button_id) {

  
// split up button name into "editorID" and "cmdID"
  var BtnParts = Array();
  BtnParts 
= button_id.split("_");
  
var objname    = button_id.replace(/^_(.*)_[^_]*$/'$1');
  
var cmdID      = BtnParts[ BtnParts.length-1 ];
  
var button_obj = document.all[button_id];
  
var editor_obj = document.all["_" +objname + "_editor"];
  
var config     = document.all[objname].config;

  
// help popup
  if (cmdID == 'showhelp'{
    window.open(_editor_url 
+ "popups/editor_help.html"'EditorHelp');
    
return;
  }


  
// popup editor
  if (cmdID == 'popupeditor'{
    window.open(_editor_url 
+ "popups/fullscreen.html?"+objname,
                
'FullScreen',
                
'toolbar=no,location=no,directories=no,status=yes,menubar=no,scrollbars=yes,resizable=yes,width=640,height=480');
    
return;
  }


  
// check editor mode (don't perform actions in textedit mode)
  if (editor_obj.tagName.toLowerCase() == 'textarea'return; }

  
var editdoc = editor_obj.contentWindow.document;
  editor_focus(editor_obj);

  
// get index and value for pulldowns
  var idx = button_obj.selectedIndex;
  
var val = (idx != null? button_obj[ idx ].value : null;

  
if (0{}   // use else if for easy cutting and pasting

  
//
  // CUSTOM BUTTONS START HERE
  //

  
// Custom1
  else if (cmdID == 'custom1'{
    alert(
"Hello, I am custom button 1!");
  }


  
// Custom2
  else if (cmdID == 'custom2'{  // insert some text from a popup window
    var myTitle = "This is a custom title";
    
var myText = showModalDialog(_editor_url + "popups/custom2.html",
                                 myTitle,      
// str or obj specified here can be read from dialog as "window.dialogArguments"
                                 "resizable: yes; help: no; status: no; scroll: no; ");
    
if (myText) { editor_insertHTML(objname, myText); }
  }


  
// Custom3
  else if (cmdID == 'custom3'{  // insert some text
    editor_insertHTML(objname, "It's easy to add buttons that insert text!");
  }


  
//
  // END OF CUSTOM BUTTONS
  //

  
// FontName
  else if (cmdID == 'FontName' && val) {
    editdoc.execCommand(cmdID,
0,val);
  }


  
// FontSize
  else if (cmdID == 'FontSize' && val) {
    editdoc.execCommand(cmdID,
0,val);
  }


  
// FontStyle (change CSS className)
  else if (cmdID == 'FontStyle' && val) {
    editdoc.execCommand(
'RemoveFormat');
    editdoc.execCommand(
'FontName',0,'636c6173734e616d6520706c616365686f6c646572');
    
var fontArray = editdoc.all.tags("FONT");
    
for (i=0; i<fontArray.length; i++{
      
if (fontArray[i].face == '636c6173734e616d6520706c616365686f6c646572'{
        fontArray[i].face 
= "";
        fontArray[i].className 
= val;
        fontArray[i].outerHTML 
= fontArray[i].outerHTML.replace(/face=['"]+/, "");
        }
    }
    button_obj.selectedIndex =0;
  }

  // fgColor and bgColor
  else if (cmdID == 
'ForeColor' || cmdID == 'BackColor') {
    var oldcolor = _dec_to_rgb(editdoc.queryCommandValue(cmdID));
    var newcolor = showModalDialog(_editor_url + "popups/select_color.html", oldcolor, "resizable: no; help: no; status: no; scroll: no;");
    if (newcolor != null) { editdoc.execCommand(cmdID, false, "#"+newcolor); }
  }

  // execute command for buttons - if we didn
'catch the cmdID by here we'll assume it's a
  
// commandID and pass it to execCommand().   See http://msdn.microsoft.com/workshop/author/dhtml/reference/commandids.asp
  else {
    
// subscript & superscript, disable one before enabling the other
    if (cmdID.toLowerCase() == 'subscript' && editdoc.queryCommandState('superscript')) { editdoc.execCommand('superscript'); }
    
if (cmdID.toLowerCase() == 'superscript' && editdoc.queryCommandState('subscript')) { editdoc.execCommand('subscript'); }

    
// insert link
    if (cmdID.toLowerCase() == 'createlink'){
      editdoc.execCommand(cmdID,
1);
    }


    
// insert image
    else if (cmdID.toLowerCase() == 'insertimage'){
      showModalDialog(_editor_url 
+ "popups/insert_image.html", editdoc, "resizable: no; help: no; status: no; scroll: no; ");
    }


    
// insert table
    else if (cmdID.toLowerCase() == 'inserttable'){
      showModalDialog(_editor_url 
+ "popups/insert_table.html?"+objname,
                                 window,
                                 
"resizable: yes; help: no; status: no; scroll: no; ");
    }


    
// all other commands microsoft Command Identifiers
    else { editdoc.execCommand(cmdID); }
  }


  editor_event(objname);
}


/* ---------------------------------------------------------------------- *
  Function    : editor_event
  Description : called everytime an editor event occurs
  Usage       : editor_event(objname, runDelay, eventName)
  Arguments   : objname - ID of textarea to replace
                runDelay: -1 = run now, no matter what
                          0  = run now, if allowed
                        1000 = run in 1 sec, if allowed at that point
* ---------------------------------------------------------------------- 
*/


function editor_event(objname,runDelay) {
  
var config = document.all[objname].config;
  
var editor_obj  = document.all["_" +objname+  "_editor"];       // html editor object
  if (runDelay == null{ runDelay = 0; }
  
var editdoc;
  
var editEvent = editor_obj.contentWindow ? editor_obj.contentWindow.event : event;

  
// catch keypress events
    if (editEvent && editEvent.keyCode) {
      
var ord       = editEvent.keyCode;    // ascii order of key pressed
      var ctrlKey   = editEvent.ctrlKey;
      
var altKey    = editEvent.altKey;
      
var shiftKey  = editEvent.shiftKey;

      
if (ord == 16return; }  // ignore shift key by itself
      if (ord == 17return; }  // ignore ctrl key by itself
      if (ord == 18return; }  // ignore alt key by itself


       
// cancel ENTER key and insert <BR> instead
//
       if (ord == 13 && editEvent.type == 'keypress') {
//
         editEvent.returnValue = false;
//
         editor_insertHTML(objname, "<br>");
//
         return;
//
       }

      
if (ctrlKey && (ord == 122 || ord == 90)) {     // catch ctrl-z (UNDO)
//
      TODO: Add our own undo/redo functionality
//
        editEvent.cancelBubble = true;
        return;
      }

      
if ((ctrlKey && (ord == 121 || ord == 89)) ||
          ctrlKey 
&& shiftKey && (ord == 122 || ord == 90)) {     // catch ctrl-y, ctrl-shift-z (REDO)
//
      TODO: Add our own undo/redo functionality
        return;
      }

    }


  
// setup timer for delayed updates (some events take time to complete)
  if (runDelay > 0return setTimeout(function(){ editor_event(objname); }, runDelay); }

  
// don't execute more than 3 times a second (eg: too soon after last execution)
  if (this.tooSoon == 1 && runDelay >= 0this.queue = 1return; } // queue all but urgent events
  this.tooSoon = 1;
  setTimeout(
function(){
    
this.tooSoon = 0;
    
if (this.queue) { editor_event(objname,-1); };
    
this.queue = 0;
    }
333);  // 1/3 second


  editor_updateOutput(objname);
  editor_updateToolbar(objname);

}


/* ---------------------------------------------------------------------- *
  Function    : editor_updateToolbar
  Description : update toolbar state
  Usage       :
  Arguments   : objname - ID of textarea to replace
                action  - enable, disable, or update (default action)
* ---------------------------------------------------------------------- 
*/


function editor_updateToolbar(objname,action) {
  
var config = document.all[objname].config;
  
var editor_obj  = document.all["_" +objname+  "_editor"];

  
// disable or enable toolbar

  
if (action == "enable" || action == "disable"{
    
var tbItems = new Array('FontName','FontSize','FontStyle');                           // add pulldowns
    for (var btnName in config.btnList) { tbItems.push(config.btnList[btnName][0]); } // add buttons

    
for (var idxN in tbItems) {
      
var cmdID = tbItems[idxN].toLowerCase();
      
var tbObj = document.all["_" +objname+ "_" +tbItems[idxN]];
      
if (cmdID == "htmlmode" || cmdID == "about" || cmdID == "showhelp" || cmdID == "popupeditor"continue; } // don't change these buttons
      if (tbObj == nullcontinue; }
      
var isBtn = (tbObj.tagName.toLowerCase() == "button"? true : false;

      
if (action == "enable")  { tbObj.disabled = falseif (isBtn) { tbObj.className = 'btn' }}
      
if (action == "disable"{ tbObj.disabled = true;  if (isBtn) { tbObj.className = 'btnNA' }}
    }

    
return;
  }


  
// update toolbar state

  
if (editor_obj.tagName.toLowerCase() == 'textarea'return; }   // don't update state in textedit mode
  var editdoc = editor_obj.contentWindow.document;

  
// Set FontName pulldown
  var fontname_obj = document.all["_" +objname+ "_FontName"];
  
if (fontname_obj) {
    
var fontname = editdoc.queryCommandValue('FontName');
    
if (fontname == null{ fontname_obj.value = null; }
    
else {
      
var found = 0;
      
for (i=0; i<fontname_obj.length; i++{
        
if (fontname.toLowerCase() == fontname_obj[i].text.toLowerCase()) {
          fontname_obj.selectedIndex 
= i;
          found 
= 1;
        }

      }

      
if (found != 1{ fontname_obj.value = null; }     // for fonts not in list
    }

  }


  
// Set FontSize pulldown
  var fontsize_obj = document.all["_" +objname+ "_FontSize"];
  
if (fontsize_obj) {
    
var fontsize = editdoc.queryCommandValue('FontSize');
    
if (fontsize == null{ fontsize_obj.value = null; }
    
else {
      
var found = 0;
      
for (i=0; i<fontsize_obj.length; i++{
        
if (fontsize == fontsize_obj[i].value) { fontsize_obj.selectedIndex = i; found=1; }
      }

      
if (found != 1{ fontsize_obj.value = null; }     // for sizes not in list
    }

  }


  
// Set FontStyle pulldown
  var classname_obj = document.all["_" +objname+ "_FontStyle"];
  
if (classname_obj) {
    
var curRange = editdoc.selection.createRange();

    
// check element and element parents for class names
    var pElement;
    
if (curRange.length) { pElement = curRange[0]; }              // control tange
    else                 { pElement = curRange.parentElement(); } // text range
    while (pElement && !pElement.className) { pElement = pElement.parentElement; }  // keep going up

    
var thisClass = pElement ? pElement.className.toLowerCase() : "";
    
if (!thisClass && classname_obj.value) { classname_obj.value = null; }
    
else {
      
var found = 0;
      
for (i=0; i<classname_obj.length; i++{
        
if (thisClass == classname_obj[i].value.toLowerCase()) {
          classname_obj.selectedIndex 
= i;
          found
=1;
        }

      }

      
if (found != 1{ classname_obj.value = null; }     // for classes not in list
    }

  }


  
// update button states
  var IDList = Array('Bold','Italic','Underline','StrikeThrough','SubScript','SuperScript','JustifyLeft','JustifyCenter','JustifyRight','InsertOrderedList','InsertUnorderedList');
  
for (i=0; i<IDList.length; i++{
    
var btnObj = document.all["_" +objname+ "_" +IDList[i]];
    
if (btnObj == nullcontinue; }
    
var cmdActive = editdoc.queryCommandState( IDList[i] );

    
if (!cmdActive)  {                                  // option is OK
      if (btnObj.className != 'btn'{ btnObj.className = 'btn'; }
      
if (btnObj.disabled  != false{ btnObj.disabled = false; }
    }
 else if (cmdActive)  {                            // option already applied or mixed content
      if (btnObj.className != 'btnDown'{ btnObj.className = 'btnDown'; }
      
if (btnObj.disabled  != false)   { btnObj.disabled = false; }
    }

  }

}


/* ---------------------------------------------------------------------- *
  Function    : editor_updateOutput
  Description : update hidden output field with data from wysiwg
* ---------------------------------------------------------------------- 
*/


function editor_updateOutput(objname) {
  
var config     = document.all[objname].config;
  
var editor_obj  = document.all["_" +objname+  "_editor"];       // html editor object
  var editEvent = editor_obj.contentWindow ? editor_obj.contentWindow.event : event;
  
var isTextarea = (editor_obj.tagName.toLowerCase() == 'textarea');
  
var editdoc = isTextarea ? null : editor_obj.contentWindow.document;

  
// get contents of edit field
  var contents;
  
if (isTextarea) { contents = editor_obj.value; }
  
else            { contents = editdoc.body.innerHTML; }

  
// check if contents has changed since the last time we ran this routine
  if (config.lastUpdateOutput && config.lastUpdateOutput == contents) return; }
  
else { config.lastUpdateOutput = contents; }

  
// update hidden output field
  document.all[objname].value = contents;

}


/* ---------------------------------------------------------------------- *
  Function    : editor_filterOutput
  Description :
* ---------------------------------------------------------------------- 
*/


function editor_filterOutput(objname) {
  editor_updateOutput(objname);
  
var contents = document.all[objname].value;
  
var config   = document.all[objname].config;

  
// ignore blank contents
  if (contents.toLowerCase() == '<p>&nbsp;</p>'{ contents = ""; }

  
// filter tag - this code is run for each HTML tag matched
  var filterTag = function(tagBody,tagName,tagAttr) {
    tagName 
= tagName.toLowerCase();
    
var closingTag = (tagBody.match(/^<//)) ? true : false;

    
// fix placeholder URLS - remove absolute paths that IE adds
    if (tagName == 'img'{ tagBody = tagBody.replace(/(srcs*=s*.)[^*]*(***)/"$1$2"); }
    
if (tagName == 'a')   { tagBody = tagBody.replace(/(hrefs*=s*.)[^*]*(***)/"$1$2"); }

    
// add additional tag filtering here

    
// convert to vbCode
//
    if      (tagName == 'b' || tagName == 'strong') {
//
      if (closingTag) { tagBody = "[/b]"; } else { tagBody = "[b]"; }
//
    }
//
    else if (tagName == 'i' || tagName == 'em') {
//
      if (closingTag) { tagBody = "[/i]"; } else { tagBody = "[i]"; }
//
    }
//
    else if (tagName == 'u') {
//
      if (closingTag) { tagBody = "[/u]"; } else { tagBody = "[u]"; }
//
    }
//
    else {
//
      tagBody = ""; // disallow all other tags!
//
    }

    
return tagBody;
  }
;

  
// match tags and call filterTag
  RegExp.lastIndex = 0;
    
var matchTag = /</?(w+)((?:[^'">]*|'[^']*'|"[^"]*")*)>/g;   // this will match tags, but still doesn't handle container tags (textarea, comments, etc)

  contents = contents.replace(matchTag, filterTag);

  // remove nextlines from output (if requested)
  if (config.replaceNextlines) {
    contents = contents.replace(/ /g, ' ');
    contents = contents.replace(/ /g, ' ');
    contents = contents.replace(/ /g, ' ');
  }

  // update output with filtered content
  document.all[objname].value = contents;

}

/* ---------------------------------------------------------------------- *
  Function    : editor_setmode
  Description : change mode between WYSIWYG and HTML editor
  Usage       : editor_setmode(objname, mode);
  Arguments   : objname - button id string with editor and action name
                mode      - init, textedit, or wysiwyg
* ---------------------------------------------------------------------- */

function editor_setmode(objname, mode) {
  var config     = document.all[objname].config;
  var editor_obj = document.all[
"_" +objname + "_editor"];

  // wait until document is fully loaded
  if (document.readyState != 'complete') {
    setTimeout(function() { editor_setmode(objname,mode) }, 25);
    return;
  }

  // define different editors
  var TextEdit   = '<textarea ID=
"_' +objname + '_editor" style="width:' +editor_obj.style.width+ '; height:' +editor_obj.style.height+ '; margin-top: -1px; margin-bottom: -1px;"></textarea>';
  var RichEdit   = '<iframe ID=
"_' +objname+ '_editor"    style="width:' +editor_obj.style.width+ '; height:' +editor_obj.style.height+ ';"></iframe>';

 // src=
"' +_editor_url+ 'popups/blank.html"

  //
  // Switch to TEXTEDIT mode
  //

  if (mode == 
"textedit" || editor_obj.tagName.toLowerCase() == 'iframe') {
    config.mode = 
"textedit";
    var editdoc = editor_obj.contentWindow.document;
    var contents = editdoc.body.createTextRange().htmlText;
    editor_obj.outerHTML = TextEdit;
    editor_obj = document.all[
"_" +objname + "_editor"];
    editor_obj.value = contents;
    editor_event(objname);

    editor_updateToolbar(objname, 
"disable");  // disable toolbar items

    // set event handlers
    editor_obj.onkeydown   = function() { editor_event(objname); }
    editor_obj.onkeypress  = function() { editor_event(objname); }
    editor_obj.onkeyup     = function() { editor_event(objname); }
    editor_obj.onmouseup   = function() { editor_event(objname); }
    editor_obj.ondrop      = function() { editor_event(objname, 100); }     // these events fire before they occur
    editor_obj.oncut       = function() { editor_event(objname, 100); }
    editor_obj.onpaste     = function() { editor_event(objname, 100); }
    editor_obj.onblur      = function() { editor_event(objname, -1); }

    editor_updateOutput(objname);
    editor_focus(editor_obj);
  }

  //
  // Switch to WYSIWYG mode
  //

  else {
    config.mode = 
"wysiwyg";
    var contents = editor_obj.value;
    if (mode == 'init') { contents = document.all[objname].value; } // on init use original textarea content

    // create editor
    editor_obj.outerHTML = RichEdit;
    editor_obj = document.all[
"_" +objname + "_editor"];

    // get iframe document object

    // create editor contents (and default styles for editor)
    var html = 
"";
    html += '<html><head> ';
    if (config.stylesheet) {
      html += '<link href=
"' +config.stylesheet+ '" rel="stylesheet" type="text/css"> ';
    }
    html += '<style> ';
    html += 'body {' +config.bodyStyle+ '}  ';
    for (var i in config.fontstyles) {
      var fontstyle = config.fontstyles[i];
      if (fontstyle.classStyle) {
        html += '.' +fontstyle.className+ ' {' +fontstyle.classStyle+ '} ';
      }
    }
    html += '</style> '
      + '</head> '
      + '<body contenteditable=
"true" topmargin=1 leftmargin=1'

// still working on this
//      + ' oncontextmenu=
"parent.editor_cMenu_generate(window,'' +objname+ '');"'
      
+'>'
      
+ contents
      
+ '</body> '
      
+ '</html> ';

    
// write to editor window
    var editdoc = editor_obj.contentWindow.document;

    editdoc.open();
    editdoc.write(html);
    editdoc.close();

    editor_updateToolbar(objname, 
"enable");  // enable toolbar items

    
// store objname under editdoc
    editdoc.objname = objname;

    
// set event handlers
    editdoc.onkeydown      = function() { editor_event(objname); }
    editdoc.onkeypress     
= function() { editor_event(objname); }
    editdoc.onkeyup        
= function() { editor_event(objname); }
    editdoc.onmouseup      
= function() { editor_event(objname); }
    editdoc.body.ondrop    
= function() { editor_event(objname, 100); }     // these events fire before they occur
    editdoc.body.oncut     = function() { editor_event(objname, 100); }
    editdoc.body.onpaste   
= function() { editor_event(objname, 100); }
    editdoc.body.onblur    
= function() { editor_event(objname, -1); }

    
// bring focus to editor
    if (mode != 'init'{             // don't focus on page load, only on mode switch
      editor_focus(editor_obj);
    }


  }


  
// Call update UI
  if (mode != 'init'{             // don't update UI on page load, only on mode switch
    editor_event(objname);
  }


}


/* ---------------------------------------------------------------------- *
  Function    : editor_focus
  Description : bring focus to the editor
  Usage       : editor_focus(editor_obj);
  Arguments   : editor_obj - editor object
* ---------------------------------------------------------------------- 
*/


function editor_focus(editor_obj) {

  
// check editor mode
  if (editor_obj.tagName.toLowerCase() == 'textarea'{         // textarea
    var myfunc = function() { editor_obj.focus(); };
    setTimeout(myfunc,
100);                                     // doesn't work all the time without delay
  }


  
else {                                                        // wysiwyg
    var editdoc = editor_obj.contentWindow.document;            // get iframe editor document object
    var editorRange = editdoc.body.createTextRange();           // editor range
    var curRange    = editdoc.selection.createRange();          // selection range

    
if (curRange.length == null &&                              // make sure it's not a controlRange
        !editorRange.inRange(curRange)) {                       // is selection in editor range
      editorRange.collapse();                                   // move to start of range
      editorRange.select();                                     // select
      curRange = editorRange;
    }

  }


}


/* ---------------------------------------------------------------------- *
  Function    : editor_about
  Description : display "about this editor" popup
* ---------------------------------------------------------------------- 
*/


function editor_about(objname) {
  showModalDialog(_editor_url 
+ "popups/about.html", window, "resizable: yes; help: no; status: no; scroll: no; ");
}


/* ---------------------------------------------------------------------- *
  Function    : _dec_to_rgb
  Description : convert dec color value to rgb hex
  Usage       : var hex = _dec_to_rgb('65535');   // returns FFFF00
  Arguments   : value   - dec value
* ---------------------------------------------------------------------- 
*/


function _dec_to_rgb(value) {
  
var hex_string = "";
  
for (var hexpair = 0; hexpair < 3; hexpair++{
    
var myByte = value & 0xFF;            // get low byte
    value >>= 8;                        // drop low byte
    var nybble2 = myByte & 0x0F;          // get low nybble (4 bits)
    var nybble1 = (myByte >> 4& 0x0F;   // get high nybble
    hex_string += nybble1.toString(16); // convert nybble to hex
    hex_string += nybble2.toString(16); // convert nybble to hex
  }

  
return hex_string.toUpperCase();
}


/* ---------------------------------------------------------------------- *
  Function    : editor_insertHTML
  Description : insert string at current cursor position in editor.  If
                two strings are specifed, surround selected text with them.
  Usage       : editor_insertHTML(objname, str1, [str2], reqSelection)
  Arguments   : objname - ID of textarea
                str1 - HTML or text to insert
                str2 - HTML or text to insert (optional argument)
                reqSelection - (1 or 0) give error if no text selected
* ---------------------------------------------------------------------- 
*/


function editor_insertHTML(objname, str1,str2, reqSel) {
  
var config     = document.all[objname].config;
  
var editor_obj = document.all["_" +objname + "_editor"];    // editor object
  if (str1 == null{ str1 = ''; }
  
if (str2 == null{ str2 = ''; }

  
// for non-wysiwyg capable browsers just add to end of textbox
  if (document.all[objname] && editor_obj == null{
    document.all[objname].focus();
    document.all[objname].value 
= document.all[objname].value + str1 + str2;
    
return;
  }


  
// error checking
  if (editor_obj == nullreturn alert("Unable to insert HTML.  Invalid object name '" +objname+ "'."); }

  editor_focus(editor_obj);

  
var tagname = editor_obj.tagName.toLowerCase();
  
var sRange;

 
// insertHTML for wysiwyg iframe
  if (tagname == 'iframe'{
    
var editdoc = editor_obj.contentWindow.document;
    sRange  
= editdoc.selection.createRange();
    
var sHtml   = sRange.htmlText;

    
// check for control ranges
    if (sRange.length) return alert("Unable to insert HTML.  Try highlighting content instead of selecting it."); }

    
// insert HTML
    var oldHandler = window.onerror;
    window.onerror 
= function() { alert("Unable to insert HTML for current selection."); return true; } // partial table selections cause errors
    if (sHtml.length) {                                 // if content selected
      if (str2) { sRange.pasteHTML(str1 +sHtml+ str2) } // surround
      else      { sRange.pasteHTML(str1); }             // overwrite
    }
 else {                                            // if insertion point only
      if (reqSel) return alert("Unable to insert HTML.  You must select something first."); }
      sRange.pasteHTML(str1 
+ str2);                    // insert strings
    }

    window.onerror 
= oldHandler;
  }


  
// insertHTML for plaintext textarea
  else if (tagname == 'textarea'{
    editor_obj.focus();
    sRange  
= document.selection.createRange();
    
var sText   = sRange.text;

    
// insert HTML
    if (sText.length) {                                 // if content selected
      if (str2) { sRange.text = str1 +sText+ str2; }  // surround
      else      { sRange.text = str1; }               // overwrite
    }
 else {                                            // if insertion point only
      if (reqSel) return alert("Unable to insert HTML.  You must select something first."); }
      sRange.text 
= str1 + str2;                        // insert strings
    }

  }

  
else { alert("Unable to insert HTML.  Unknown object tag type '" +tagname+ "'."); }

  
// move to end of new content
  sRange.collapse(false); // move to end of range
  sRange.select();        // re-select

}


/* ---------------------------------------------------------------------- *
  Function    : editor_getHTML
  Description : return HTML contents of editor (in either wywisyg or html mode)
  Usage       : var myHTML = editor_getHTML('objname');
* ---------------------------------------------------------------------- 
*/


function editor_getHTML(objname) {
  
var editor_obj = document.all["_" +objname + "_editor"];
  
var isTextarea = (editor_obj.tagName.toLowerCase() == 'textarea');

  
if (isTextarea) return editor_obj.value; }
  
else            return editor_obj.contentWindow.document.body.innerHTML; }
}


/* ---------------------------------------------------------------------- *
  Function    : editor_setHTML
  Description : set HTML contents of editor (in either wywisyg or html mode)
  Usage       : editor_setHTML('objname',"<b>html</b> <u>here</u>");
* ---------------------------------------------------------------------- 
*/


function editor_setHTML(objname, html) {
  
var editor_obj = document.all["_" +objname + "_editor"];
  
var isTextarea = (editor_obj.tagName.toLowerCase() == 'textarea');

  
if (isTextarea) { editor_obj.value = html; }
  
else            { editor_obj.contentWindow.document.body.innerHTML = html; }
}


/* ---------------------------------------------------------------------- *
  Function    : editor_appendHTML
  Description : append HTML contents to editor (in either wywisyg or html mode)
  Usage       : editor_appendHTML('objname',"<b>html</b> <u>here</u>");
* ---------------------------------------------------------------------- 
*/


function editor_appendHTML(objname, html) {
  
var editor_obj = document.all["_" +objname + "_editor"];
  
var isTextarea = (editor_obj.tagName.toLowerCase() == 'textarea');

  
if (isTextarea) { editor_obj.value += html; }
  
else            { editor_obj.contentWindow.document.body.innerHTML += html; }
}


/* ---------------------------------------------------------------- */

function _isMouseOver(obj,event) {       // determine if mouse is over object
  var mouseX    = event.clientX;
  
var mouseY    = event.clientY;

  
var objTop    = obj.offsetTop;
  
var objBottom = obj.offsetTop + obj.offsetHeight;
  
var objLeft   = obj.offsetLeft;
  
var objRight  = obj.offsetLeft + obj.offsetWidth;

  
if (mouseX >= objLeft && mouseX <= objRight &&
      mouseY 
>= objTop  && mouseY <= objBottom) return true; }

  
return false;
}


/* ---------------------------------------------------------------- */

function editor_cMenu_generate(editorWin,objname) {
  
var parentWin = window;
  editorWin.event.returnValue 
= false;  // cancel default context menu

  
// define content menu options
  var cMenuOptions = [ // menu name, shortcut displayed, javascript code
    ['Cut''Ctrl-X'function() {}],
    [
'Copy''Ctrl-C'function() {}],
    [
'Paste''Ctrl-C'function() {}],
    [
'Delete''DEL'function() {}],
    [
'---'nullnull],
    [
'Select All''Ctrl-A'function() {}],
    [
'Clear All'''function() {}],
    [
'---'nullnull],
    [
'About this editor...'''function() {
      alert(
"about this editor");
    }
]];
    editor_cMenu.options 
= cMenuOptions; // save options

  
// generate context menu
  var cMenuHeader = ''
    
+ '<div id="_'+objname+'_cMenu" onblur="editor_cMenu(this);" oncontextmenu="return false;" onselectstart="return false"'
    
+ '  style="position: absolute; visibility: hidden; cursor: default; width: 167px; background-color: threedface;'
    
+ '         border: solid 1px; border-color: threedlightshadow threeddarkshadow threeddarkshadow threedlightshadow;">'
    
+ '<table border=0 cellspacing=0 cellpadding=0 width="100%" style="width: 167px; background-color: threedface; border: solid 1px; border-color: threedhighlight threedshadow threedshadow threedhighlight;">'
    
+ ' <tr><td colspan=2 height=1></td></tr>';

  
var cMenuList = '';

  
var cMenuFooter = ''
    
+ ' <tr><td colspan=2 height=1></td></tr>'
    
+ '</table></div>';

  
for (var menuIdx in editor_cMenu.options) {
    
var menuName = editor_cMenu.options[menuIdx][0];
    
var menuKey  = editor_cMenu.options[menuIdx][1];
    
var menuCode = editor_cMenu.options[menuIdx][2];

    
// separator
    if (menuName == "---" || menuName == "separator"{
      cMenuList 
+= ' <tr><td colspan=2 class="cMenuDivOuter"><div class="cMenuDivInner"></div></td></tr>';
    }


    
// menu option
    else {
      cMenuList 
+= '<tr class="cMenu" onMouseOver="editor_cMenu(this)" onMouseOut="editor_cMenu(this)" onClick="editor_cMenu(this, '' +menuIdx+ '','' +objname+ '')">';
      
if (menuKey) { cMenuList += ' <td align=left class="cMenu">' +menuName+ '</td><td align=right class="cMenu">' +menuKey+ '</td>'; }
      
else         { cMenuList += ' <td colspan=2 class="cMenu">' +menuName+ '</td>'; }
      cMenuList 
+= '</tr>';
    }

  }


  
var cMenuHTML = cMenuHeader + cMenuList + cMenuFooter;


  document.all[
'_'+objname+'_cMenu'].outerHTML = cMenuHTML;

  editor_cMenu_setPosition(parentWin, editorWin, objname);

  parentWin[
'_'+objname+'_cMenu'].style.visibility = 'visible';
  parentWin[
'_'+objname+'_cMenu'].focus();

}


/* ---------------------------------------------------------------- */

function editor_cMenu_setPosition(parentWin, editorWin, objname) {      // set object position that won't overlap window edge
  var event    = editorWin.event;
  
var cMenuObj = parentWin['_'+objname+'_cMenu'];
  
var mouseX   = event.clientX + parentWin.document.all['_'+objname+'_editor'].offsetLeft;
  
var mouseY   = event.clientY + parentWin.document.all['_'+objname+'_editor'].offsetTop;
  
var cMenuH   = cMenuObj.offsetHeight;
  
var cMenuW   = cMenuObj.offsetWidth;
  
var pageH    = document.body.clientHeight + document.body.scrollTop;
  
var pageW    = document.body.clientWidth + document.body.scrollLeft;

  
// set horzontal position
  if (mouseX + 5 + cMenuW > pageW) var left = mouseX - cMenuW - 5; } // too far right
  else                            var left = mouseX + 5; }

  
// set vertical position
  if (mouseY + 5 + cMenuH > pageH) var top = mouseY - cMenuH + 5; } // too far down
  else                            var top = mouseY + 5; }

  cMenuObj.style.top 
= top;
  cMenuObj.style.left 
= left;

}


/* ---------------------------------------------------------------- */

function editor_cMenu(obj,menuIdx,objname) {
  
var action = event.type;
  
if      (action == "mouseover" && !obj.disabled && obj.tagName.toLowerCase() == 'tr'{
    obj.className 
= 'cMenuOver';
    
for (var i=0; i < obj.cells.length; i++{ obj.cells[i].className = 'cMenuOver'; }
  }

  
else if (action == "mouseout" && !obj.disabled && obj.tagName.toLowerCase() == 'tr')  {
    obj.className 
= 'cMenu';
    
for (var i=0; i < obj.cells.length; i++{ obj.cells[i].className = 'cMenu'; }
  }

  
else if (action == "click" && !obj.disabled) {
    document.all[
'_'+objname+'_cMenu'].style.visibility = "hidden";
    
var menucode = editor_cMenu.options[menuIdx][2];
    menucode();
  }

  
else if (action == "blur"{
    
if (!_isMouseOver(obj,event)) { obj.style.visibility = 'hidden'; }
    
else {
      
if (obj.style.visibility != "hidden"{ obj.focus(); }
    }

  }

  
else { alert("editor_cMenu, unknown action: " + action); }
}


/* ---------------------------------------------------------------------- */
//创建以新的配置的对象
function newConfig(contentName)
{
    
var config = new Object();    // 创建一个新的配置对象
        config.width = "800px";
        config.height 
= "400px";
        config.bodyStyle 
= 'background-color: white; font-family: "Verdana"; font-size: x-small;';
        config.debug 
= 0;
        
// NOTE:  You can remove any of these blocks and use the default config!
        config.toolbar = [
                            [
'fontname'],
                            [
'fontsize'],
                            [
'fontstyle'],
                            [
'linebreak'],
                            [
'bold','italic','underline','separator'],
                        
//  ['strikethrough','subscript','superscript','separator'],
                            ['justifyleft','justifycenter','justifyright','separator'],
                            [
'OrderedList','UnOrderedList','Outdent','Indent','separator'],
                            [
'forecolor','backcolor','separator'],
                        
//    ['HorizontalRule','Createlink','InsertImage','htmlmode','separator'],
                        //    ['about','help','popupeditor'],
                        ];

        
// 配置对象的字体
        config.fontnames = {
                            
"宋体":       "宋体",
                            
"Arial":           "arial, helvetica, sans-serif",
                            
"Courier New":     "courier new, courier, mono",
                            
"Georgia":         "Georgia, Times New Roman, Times, Serif",
                            
"Tahoma":          "Tahoma, Arial, Helvetica, sans-serif",
                            
"Times New Roman""times new roman, times, serif",
                            
"Verdana":         "Verdana, Arial, Helvetica, sans-serif",
                            
"impact":          "impact",
                            
"WingDings":       "WingDings"
                        }
;
        
// 配置字体的大小
        config.fontsizes = {
                            
"1 (8 pt)":  "1",
                            
"2 (10 pt)""2",
                            
"3 (12 pt)""3",
                            
"4 (14 pt)""4",
                            
"5 (18 pt)""5",
                            
"6 (24 pt)""6",
                            
"7 (36 pt)""7"
                          }
;

        
// 配置字体的样式
//
//    config.stylesheet = "http://www.domain.com/sample.css";

          
// 配置字体的样式
        config.fontstyles = [   // make sure classNames are defined in the page the content is being display as well in or they won't work!
                                  { name: "headline",     className: "headline",  classStyle: "font-family: arial black, arial; font-size: 28px; letter-spacing: -2px;" },
                                  
{ name: "arial red",    className: "headline2", classStyle: "font-family: arial black, arial; font-size: 12px; letter-spacing: -2px; color:red" },
                                  
{ name: "verdana blue", className: "headline4", classStyle: "font-family: verdana; font-size: 18px; letter-spacing: -2px; color:blue" }
                            
// leave classStyle blank if it's defined in config.stylesheet (above), like this:
                            //  { name: "verdana blue", className: "headline4", classStyle: "" }
                            ];

        
// 设置对象,和对象的样式
        editor_generate(contentName,config); // 指定输入区域的样式
}

//创建以新的配置的对象:信息修改部分
function update_newConfig()
{
    
var config = new Object();    // 创建一个新的配置对象
        config.width = "800px";
        config.height 
= "400px";
        config.bodyStyle 
= 'background-color: white; font-family: "Verdana"; font-size: x-small;';
        config.debug 
= 0;
        
// NOTE:  You can remove any of these blocks and use the default config!
        config.toolbar = [
                            [
'fontname'],
                            [
'fontsize'],
                            [
'fontstyle'],
                            [
'linebreak'],
                            [
'bold','italic','underline','separator'],
                        
//  ['strikethrough','subscript','superscript','separator'],
                            ['justifyleft','justifycenter','justifyright','separator'],
                            [
'OrderedList','UnOrderedList','Outdent','Indent','separator'],
                            [
'forecolor','backcolor','separator'],
                        
//    ['HorizontalRule','Createlink','InsertImage','htmlmode','separator'],
                            ['about','help','popupeditor'],
                        ];

        
// 配置对象的字体
        config.fontnames = {
                            
"宋体":       "宋体",
                            
"Arial":           "arial, helvetica, sans-serif",
                            
"Courier New":     "courier new, courier, mono",
                            
"Georgia":         "Georgia, Times New Roman, Times, Serif",
                            
"Tahoma":          "Tahoma, Arial, Helvetica, sans-serif",
                            
"Times New Roman""times new roman, times, serif",
                            
"Verdana":         "Verdana, Arial, Helvetica, sans-serif",
                            
"impact":          "impact",
                            
"WingDings":       "WingDings"
                        }
;
        
// 配置字体的大小
        config.fontsizes = {
                            
"1 (8 pt)":  "1",
                            
"2 (10 pt)""2",
                            
"3 (12 pt)""3",
                            
"4 (14 pt)""4",
                            
"5 (18 pt)""5",
                            
"6 (24 pt)""6",
                            
"7 (36 pt)""7"
                          }
;

        
// 配置字体的样式
//
//    config.stylesheet = "http://www.domain.com/sample.css";

          
// 配置字体的样式
        config.fontstyles = [   // make sure classNames are defined in the page the content is being display as well in or they won't work!
                                  { name: "headline",     className: "headline",  classStyle: "font-family: arial black, arial; font-size: 28px; letter-spacing: -2px;" },
                                  
{ name: "arial red",    className: "headline2", classStyle: "font-family: arial black, arial; font-size: 12px; letter-spacing: -2px; color:red" },
                                  
{ name: "verdana blue", className: "headline4", classStyle: "font-family: verdana; font-size: 18px; letter-spacing: -2px; color:blue" }
                            
// leave classStyle blank if it's defined in config.stylesheet (above), like this:
                            //  { name: "verdana blue", className: "headline4", classStyle: "" }
                            ];

        
// 设置对象,和对象的样式
        editor_generate('content',config); // 指定中文输入区域的样式
}

//浏览器版本的控制
function browserControl()
{
    _editor_url 
= ""// 当前文件的绝对的路径
    var win_ie_ver = parseFloat(navigator.appVersion.split("MSIE")[1]);  // 获得IE浏览器的版本号
    /*
     *  判断其他浏览器的方式
     
*/

    
if (navigator.userAgent.indexOf('Mac')        >= 0{ win_ie_ver = 0; }
    
if (navigator.userAgent.indexOf('Windows CE'>= 0{ win_ie_ver = 0; }
    
if (navigator.userAgent.indexOf('Opera')      >= 0{ win_ie_ver = 0; }
                    
// 这里是判断浏览器,需要IE5.5以上的版本支持
    if (win_ie_ver >= 5.5{
//        document.write('<scr'+'ipt src="' +_editor_url+ 'js/editor.js" language="Javascript1.2"></scr'+'ipt>');
    }
 else {
            alert(
"不支持当前浏览器的版本");
            document.write(
'<scr'+'ipt>function editor_generate() { return false; }</scr'+'ipt>');
    }

// -->
}

使用该js只需要三个步骤:

    1.通过<script language="javascript" src="js/editor.js" type="text/javascript""></script>引入该控件所在的文件;

   2 调用browserControl()函数来判断客户端的浏览器类型,对不同的浏览器作不同的操作;

   3. 调用newConfig()函数,将指定的textarea域设定为文本编辑区域.

经过该编辑器格式化的文字内容提交到数据库以后,从数据库中直接以字符串的格式取出来放在jsp页面中,就可以显示出原来发布时的 格式效果,这是因为javascirpt脚本已经对格式化文本做了特殊处理,比如加粗文字"加粗"实际上存储的是"<b>加粗</b>"字符串。因此,显示页面无需作特殊处理,就可以恢复原文字的格式信息了。

2.tree.js &&  tree_tpl.js

这两个js主要实现了树型结构的展现,构造出树型菜单。

tree_tpl.js:

 

/*
    Feel free to use your custom images for the tree. Make sure they are all of the same size.
    User images collections are welcome, we'll publish them giving all regards.
*/


var tree_tpl = {
    
'target'  : 'mainFrame',    // name of the frame links will be opened in
                            // other possible values are: _blank, _parent, _search, _self and _top

    
'icon_e'  : 'images/empty.gif'// empty image
    'icon_l'  : 'images/line.gif',  // vertical line

    
'icon_32' : 'images/base.gif',   // root icon normal    
    'icon_36' : 'images/base.gif',   // root icon normal    
    
    
    
'icon_48' : 'images/base.gif',   // root icon normal
    'icon_52' : 'images/base.gif',   // root icon selected
    'icon_56' : 'images/base.gif',   // root icon opened
    'icon_60' : 'images/base.gif',   // root icon selected
    
    
'icon_16' : 'images/folder.gif'// node icon normal
    'icon_20' : 'images/folderopen.gif'// node icon selected
    'icon_24' : 'images/folder.gif'// node icon opened
    'icon_28' : 'images/folderopen.gif'// node icon selected opened

    
'icon_0'  : 'images/page.gif'// leaf icon normal
    'icon_4'  : 'images/page.gif'// leaf icon selected
    'icon_8'  : 'images/page.gif'// leaf icon opened
    'icon_12' : 'images/page.gif'// leaf icon selected
    
    
'icon_2'  : 'images/joinbottom.gif'// junction for leaf
    'icon_3'  : 'images/join.gif',       // junction for last leaf
    'icon_18' : 'images/plusbottom.gif'// junction for closed node
    'icon_19' : 'images/plus.gif',       // junctioin for last closed node
    'icon_26' : 'images/minusbottom.gif',// junction for opened node
    'icon_27' : 'images/minus.gif'       // junctioin for last opended node
}
;

tree.js:

 

// Title: Tigra Tree
//
 Description: See the demo at url
//
 URL: http://www.softcomplex.com/products/tigra_menu_tree/
//
 Version: 1.0
//
 Date: 07-20-2002 (mm-dd-yyyy)
//
 Contact: feedback@softcomplex.com (specify product title in the subject)
//
 Notes: Registration needed to use this script on your web site.
//
     Registration for this version (1.0) is free of charge.
//
    Visit official site for details

function tree (a_items, a_template) {

    
this.a_tpl      = a_template;
    
this.a_config   = a_items;
    
this.o_root     = this;
    
this.a_index    = [];
    
this.o_selected = null;
    
this.n_depth    = -1;
    
    
var o_icone = new Image(),
        o_iconl 
= new Image();
    o_icone.src 
= a_template['icon_e'];
    o_iconl.src 
= a_template['icon_l'];
    a_template[
'im_e'= o_icone;
    a_template[
'im_l'= o_iconl;
    
for (var i = 0; i < 64; i++)
        
if (a_template['icon_' + i]) {
            
var o_icon = new Image();
            a_template[
'im_' + i] = o_icon;
            o_icon.src 
= a_template['icon_' + i];
        }

    
    
this.toggle = function (n_id) {    var o_item = this.a_index[n_id]; o_item.open(o_item.b_opened) };
    
this.select = function (n_id) return this.a_index[n_id].select(); };
    
this.mout   = function (n_id) this.a_index[n_id].upstatus(true) };
    
this.mover  = function (n_id) this.a_index[n_id].upstatus() };

    
this.a_children = [];
    
for (var i = 0; i < a_items.length; i++)
        
new tree_item(this, i);

    
this.n_id = trees.length;
    trees[
this.n_id] = this;
    
    
for (var i = 0; i < this.a_children.length; i++{
        document.write(
this.a_children[i].init());
        
this.a_children[i].open();
    }

}

function tree_item (o_parent, n_order) {

    
this.n_depth  = o_parent.n_depth + 1;
    
this.a_config = o_parent.a_config[n_order + (this.n_depth ? 2 : 0)];
    
if (!this.a_config) return;

    
this.o_root    = o_parent.o_root;
    
this.o_parent  = o_parent;
    
this.n_order   = n_order;
    
this.b_opened  = !this.n_depth;

    
this.n_id = this.o_root.a_index.length;
    
this.o_root.a_index[this.n_id] = this;
    o_parent.a_children[n_order] 
= this;

    
this.a_children = [];
    
for (var i = 0; i < this.a_config.length - 2; i++)
        
new tree_item(this, i);

    
this.get_icon = item_get_icon;
    
this.open     = item_open;
    
this.select   = item_select;
    
this.init     = item_init;
    
this.upstatus = item_upstatus;
    
this.is_last  = function () return this.n_order == this.o_parent.a_children.length - 1 };
}


function item_open (b_close) {
    
var o_idiv = get_element('i_div' + this.n_id);
    
if (!o_idiv) return;
    
    
if (!o_idiv.innerHTML) {
        
var a_children = [];
        
for (var i = 0; i < this.a_children.length; i++)
            a_children[i]
= this.a_children[i].init();
        o_idiv.innerHTML 
= a_children.join('');
    }

    o_idiv.style.display 
= (b_close ? 'none' : 'block');
    
    
this.b_opened = !b_close;
    
var o_jicon = document.images['j_img' + this.n_id],
        o_iicon 
= document.images['i_img' + this.n_id];
    
if (o_jicon) o_jicon.src = this.get_icon(true);
    
if (o_iicon) o_iicon.src = this.get_icon();
    
this.upstatus();
}


function item_select (b_deselect) {
    
if (!b_deselect) {
        
var o_olditem = this.o_root.o_selected;
        
this.o_root.o_selected = this;
        
if (o_olditem) o_olditem.select(true);
    }

    
var o_iicon = document.images['i_img' + this.n_id];
    
if (o_iicon) o_iicon.src = this.get_icon();
    get_element(
'i_txt' + this.n_id).style.fontWeight = b_deselect ? 'normal' : 'bold';
    
    
this.upstatus();
    
return Boolean(this.a_config[1]);
}


function item_upstatus (b_clear) {
    window.setTimeout(
'window.status="' + (b_clear ? '' : this.a_config[0+ (this.a_config[1? ' ('+ this.a_config[1+ ')' : '')) + '"'10);
}


function item_init () {
    
var a_offset = [],
        o_current_item 
= this.o_parent;
    
for (var i = this.n_depth; i > 1; i--{
        a_offset[i] 
= '<img src="' + this.o_root.a_tpl[o_current_item.is_last() ? 'icon_e' : 'icon_l'+ '" border="0" align="absbottom">';
        o_current_item 
= o_current_item.o_parent;
    }

    
return '<table cellpadding="0" cellspacing="0" border="0"><tr><td nowrap>' + (this.n_depth ? a_offset.join(''+ (this.a_children.length ? '<a href="javascript: trees[' + this.o_root.n_id + '].toggle(' + this.n_id + ')" onmouseover="trees[' + this.o_root.n_id + '].mover(' + this.n_id + ')" onmouseout="trees[' + this.o_root.n_id + '].mout(' + this.n_id + ')"><img src="' + this.get_icon(true+ '" border="0" align="absbottom" name="j_img' + this.n_id + '"></a>' : '<img src="' + this.get_icon(true+ '" border="0" align="absbottom">') : ''+ '<a href="' + this.a_config[1+ '" target="' + this.o_root.a_tpl['target'+ '" onclick="return trees[' + this.o_root.n_id + '].select(' + this.n_id + ')" ondblclick="trees[' + this.o_root.n_id + '].toggle(' + this.n_id + ')" onmouseover="trees[' + this.o_root.n_id + '].mover(' + this.n_id + ')" onmouseout="trees[' + this.o_root.n_id + '].mout(' + this.n_id + ')" class="t' + this.o_root.n_id + 'i" id="i_txt' + this.n_id + '"><img src="' + this.get_icon() + '" border="0" align="absbottom" name="i_img' + this.n_id + '" class="t' + this.o_root.n_id + 'im">' + this.a_config[0+ '</a></td></tr></table>' + (this.a_children.length ? '<div id="i_div' + this.n_id + '" style="display:none"></div>' : '');
}


function item_get_icon (b_junction) {
//    alert('icon_' + ((this.n_depth ? 0 : 32) + (this.a_children.length ? 16 : 0) + (this.a_children.length && this.b_opened ? 8 : 0) + (!b_junction && this.o_root.o_selected == this ? 4 : 0) + (b_junction ? 2 : 0) + (b_junction && this.is_last() ? 1 : 0)));
    return this.o_root.a_tpl['icon_' + ((this.n_depth ? 0 : 32+ (this.a_children.length ? 16 : 0+ (this.a_children.length && this.b_opened ? 8 : 0+ (!b_junction && this.o_root.o_selected == this ? 4 : 0+ (b_junction ? 2 : 0+ (b_junction && this.is_last() ? 1 : 0))];

}


var trees = [];
get_element 
= document.all ?
    
function (s_id) return document.all[s_id] } :
    
function (s_id) return document.getElementById(s_id) };

 

 

这是一次测试:

<%@page contentType="text/html; charset=GBK" language="java" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  
<head>
    
<base href="<%=basePath%>">
    
    
<title>My JSP 'index.jsp' starting page</title>
    
<meta http-equiv="pragma" content="no-cache">
    
<meta http-equiv="cache-control" content="no-cache">
    
<meta http-equiv="expires" content="0">    
    
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    
<meta http-equiv="description" content="This is my page">
    
<!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    
-->
  
</head>
  
  
<body>
  
  
<script language="javascript1.2" src="./js/editor.js" type="text/javascript"></script>
      
<script language="Javascript1.2">browserControl()</script>
      
        
<textarea name="content" style="width:100%; height:80"></textarea>
        
<script language="javascript1.2">newConfig('content')</script>
    
<%StringBuffer strBuf = new StringBuffer();    //构造字符串
    strBuf.append(
"['根','some/path/to/my/url?column=1',"+" "+
     
"['根-叶结点1','some/path/to/my/url?column=2']],"+
      
"['根','some/path/to/my/url?column=3',"+" "+
     
"['根-叶结点2','some/path/to/my/url?column=4']],");
     
%>
    
<script language="JavaScript" src="./js/tree.js"></script> <script language="JavaScript">

var TREE_ITEMS = [
 
<%=strBuf.toString()%>
];

</script> <script language="JavaScript" src="./js/tree_tpl.js"></script> <script language="JavaScript">

    
new tree (TREE_ITEMS, tree_tpl);

</script> 
  test!
    
  
</body>
</html>