第 5 步
返回富文本编辑器的基本原理与实践
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
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
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
35 YAHOO.realazy.RTE.prototype = {
36
37
40 render: function(){
41 42 this._createIframeAndHideTextarea();
43 44 this._turnOnDesignMode();
45 46 this._buildToolbar();
47 48 this._bindToolbarEvents();
49 },
50
54 _createIframeAndHideTextarea: function(){
55 var iframe = document.createElement('iframe');
56 $D.addClass(iframe, 'rte-iframe');
57 this.textarea.style.display = 'none';
58 $D.insertBefore(iframe, this.textarea);
59 this.iframe = iframe;
60 },
61
65 _getWin: function(){
66 return this.iframe.contentWindow;
67 },
68
69
73 _getDoc: function(){
74 return this._getWin().document;
75 },
76
77
81 _turnOnDesignMode: function(){
82 try {
83 this._getDoc().open();
84 this._getDoc().write(YAHOO.realazy.RTE.htmlContent.replace(/{CONTENT}/, this.textarea.value));
85 this._getDoc().close();
86 this._getDoc().designMode = 'on';
87 } catch(ex) {
88 setTimeout(arguments.callee, 0);
89 return;
90 }
91 },
92
93
97 _buildToolbar: function(){
98 var toolbar = document.createElement('div');
99 $D.addClass(toolbar, 'rte-toolbar');
100
101 var items = {
102 'fontname': {
103 'Arial': 'Arial',
104 '宋体': "SimSun, STSong, 'LiSong Pro'",
105 '黑体': "SimHei, STHeiti, 'LiHei Pro'"
106 },
107 'fontsize': {
108 '最小': 1,
109 '较小': 2,
110 '小': 3,
111 '中': 4,
112 '大': 5,
113 '较大': 6,
114 '最大': 7
115 },
116 'bold': '加粗',
117 'italic': '斜体',
118 'underline': '下划线',
119 'justifyleft': '居左',
120 'justifycenter': '居中',
121 'justifyright': '居右',
122 'createlink': '超链接',
123 'insertimage': '插图'
124 }
125
126 for (var k in items){
127 var span = document.createElement('span');
128 if (k == 'fontname' || k == 'fontsize'){
129 var select = document.createElement('select');
130 $D.addClass(select, k);
131 for (var kk in items[k]){
132 var option = new Option(kk, items[k][kk]);
133 if (!isGecko)
134 select.add(option);
135 else
136 select.appendChild(option);
137 }
138 span.appendChild(select);
139 this.toolbarItems[k] = select;
140 } else {
141 $D.addClass(span, k);
142 span.innerHTML = items[k];
143 this.toolbarItems[k] = span;
144 }
145 toolbar.appendChild(span);
146 }
147
148 $D.insertBefore(toolbar, this.iframe);
149 this.toolbar = toolbar;
150 },
151
157 _execCommand: function(sCmd, sVal){
158 this._getWin().focus();
159 this._getDoc().execCommand(sCmd, false, sVal);
160 },
161
162
166 _bindToolbarEvents: function(){
167 var _this = this,
168 items = this.toolbarItems,
169 trim = YAHOO.lang.trim;
170
171 $E.on([items['fontsize'], items['fontname']], 'change', function(e){
172 var cmd = this.className,
173 val = this.options[this.selectedIndex].value;
174 _this._execCommand(cmd, val);
175 });
176
177 $E.on(this.toolbar, 'click', function(e){
178 var t = $E.getTarget(e),
179 cmd = t.className,
180 nn = t.nodeName.toLowerCase(),
181 val = null,
182 isNeedVal = false;
183 if (nn != 'span' && !cmd) return;
184 switch (cmd){
185 case 'createlink':
186 case 'insertimage':
187 isNeedVal = true;
188 val = prompt('请输入网址:', 'http://');
189 break;
190 case 'fontname':
191 case 'fontsize':
192 return;
193 default:
194 break;
195 }
196
197 if (isNeedVal && (!val || (trim(val) == 'http://'))) return;
198 this._execCommand(cmd, val);
199
200 }, this, true);
201 }
202 }
203 })();