第 4 步

返回富文本编辑器的基本原理与实践

    1 if (!YAHOO.realazy)
    2     YAHOO.realazy = {};
    3 
    4 if (!YAHOO.realazy.RTE)
    5     YAHOO.realazy.RTE = {};
    6 
    7 (function(){
    8     var $D = YAHOO.util.Dom,
    9         $E = YAHOO.util.Event;
   10 
   11     var ua = YAHOO.env.ua,
   12         isIE = ua.ie,
   13         isGecko = ua.gecko,
   14         isOpera = ua.opera,
   15         isWebkit = ua.webkit;
   16 
   17     /**
   18      * 替换 textarea, 实现 user-editable 的内容区域
   19      * @param {string | HTMLElement} elTextarea 需替换的 textarea 元素的 id 或者引用
   20      * @class
   21      */
   22     YAHOO.realazy.RTE = function(elTextarea){
   23         if ('string' == typeof elTextarea) elTextarea = $D.get(elTextarea);
   24         this.textarea = elTextarea;
   25         this.toolbarItems = {};
   26     }
   27 
   28     /**
   29      * 预填充 iframe 的内容
   30      *
   31      */
   32     YAHOO.realazy.RTE.htmlContent =  ['<!DOCTYPE HTML PUBLIC "-/','/W3C/','/DTD HTML 4.01/','/EN" "http:/','/www.w3.org/TR/html4/strict.dtd"><html><head><title>编辑页面</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /></head><body>{CONTENT}</body></html>'].join('');
   33 
   34     /** @scope YAHOO.realazy.RTE.prototype */
   35     YAHOO.realazy.RTE.prototype = {
   36         
   37         /**
   38          * 生成编辑器
   39          */
   40         render: function(){
   41             // step 1: 生成 iframe 并隐藏 textarea
   42             this._createIframeAndHideTextarea();
   43             // step 2: 开启 iframe 的 designMode
   44             this._turnOnDesignMode();
   45             // step 3: 建立 toolbar
   46             this._buildToolbar();
   47         },
   48         /**
   49          * 生成 iframe 并隐藏 textarea
   50          * @private
   51          */
   52         _createIframeAndHideTextarea: function(){
   53             var iframe = document.createElement('iframe');
   54             $D.addClass(iframe, 'rte-iframe');
   55             this.textarea.style.display = 'none';
   56             $D.insertBefore(iframe, this.textarea);
   57             this.iframe = iframe;
   58         },
   59         /**
   60          * 获取 iframe 的 contentWindow
   61          * @private
   62          */
   63         _getWin: function(){
   64             return this.iframe.contentWindow;
   65         },
   66 
   67         /**
   68          * 获取 iframe 的 document
   69          * @private
   70          */
   71         _getDoc: function(){
   72             return this._getWin().document;
   73         },
   74 
   75         /**
   76          * 开启 iframe 的 design mode
   77          * @private
   78          */
   79         _turnOnDesignMode: function(){
   80             try {
   81                 this._getDoc().open();
   82                 this._getDoc().write(YAHOO.realazy.RTE.htmlContent.replace(/{CONTENT}/, this.textarea.value));
   83                 this._getDoc().close();
   84                 this._getDoc().designMode = 'on';
   85             } catch(ex) {
   86                 setTimeout(arguments.callee, 0);
   87                 return;
   88             }
   89         },
   90 
   91         /**
   92          * 建立 editor 的 toolbar
   93          * @private
   94          */
   95         _buildToolbar: function(){
   96             var toolbar = document.createElement('div');
   97             $D.addClass(toolbar, 'rte-toolbar');
   98 
   99             var items = {
  100                 'fontname': {
  101                     'Arial': 'Arial',
  102                     '宋体': "SimSun, STSong, 'LiSong Pro'", 
  103                     '黑体': "SimHei, STHeiti, 'LiHei Pro'"
  104                 },
  105                 'fontsize': {
  106                     '最小': 1,
  107                     '较小': 2,
  108                     '': 3,
  109                     '': 4,
  110                     '': 5,
  111                     '较大': 6,
  112                     '最大': 7
  113                 },
  114                 'bold': '加粗',
  115                 'italic': '斜体',
  116                 'underline': '下划线',
  117                 'justifyleft': '居左',
  118                 'justifycenter': '居中',
  119                 'justifyright': '居右',
  120                 'createlink': '超链接',
  121                 'insertimage': '插图'
  122             }
  123             
  124             for (var k in items){
  125                 var span = document.createElement('span');
  126                 if (k == 'fontname' || k == 'fontsize'){
  127                     var select = document.createElement('select');
  128                     $D.addClass(select, k);
  129                     for (var kk in items[k]){
  130                         var option = new Option(kk, items[k][kk]);
  131                         if (!isGecko)
  132                             select.add(option);
  133                         else
  134                             select.appendChild(option);
  135                     }
  136                     span.appendChild(select);
  137                     this.toolbarItems[k] = select;
  138                 } else {
  139                     $D.addClass(span, k);
  140                     span.innerHTML = items[k];
  141                     this.toolbarItems[k] = span;
  142                 }
  143                 toolbar.appendChild(span);
  144             }
  145             
  146             $D.insertBefore(toolbar, this.iframe);
  147             this.toolbar = toolbar;
  148         }
  149     }
  150 })();