第 6 步
返回富文本编辑器的基本原理与实践
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 if (isIE)
51 this._setToolbarItemUnselectable();
52 },
53
57 _createIframeAndHideTextarea: function(){
58 var iframe = document.createElement('iframe');
59 $D.addClass(iframe, 'rte-iframe');
60 this.textarea.style.display = 'none';
61 $D.insertBefore(iframe, this.textarea);
62 this.iframe = iframe;
63 },
64
68 _getWin: function(){
69 return this.iframe.contentWindow;
70 },
71
72
76 _getDoc: function(){
77 return this._getWin().document;
78 },
79
80
84 _turnOnDesignMode: function(){
85 try {
86 this._getDoc().open();
87 this._getDoc().write(YAHOO.realazy.RTE.htmlContent.replace(/{CONTENT}/, this.textarea.value));
88 this._getDoc().close();
89 this._getDoc().designMode = 'on';
90 } catch(ex) {
91 setTimeout(arguments.callee, 0);
92 return;
93 }
94 },
95
96
100 _buildToolbar: function(){
101 var toolbar = document.createElement('div');
102 $D.addClass(toolbar, 'rte-toolbar');
103
104 var items = {
105 'fontname': {
106 'Arial': 'Arial',
107 '宋体': "SimSun, STSong, 'LiSong Pro'",
108 '黑体': "SimHei, STHeiti, 'LiHei Pro'"
109 },
110 'fontsize': {
111 '最小': 1,
112 '较小': 2,
113 '小': 3,
114 '中': 4,
115 '大': 5,
116 '较大': 6,
117 '最大': 7
118 },
119 'bold': '加粗',
120 'italic': '斜体',
121 'underline': '下划线',
122 'justifyleft': '居左',
123 'justifycenter': '居中',
124 'justifyright': '居右',
125 'createlink': '超链接',
126 'insertimage': '插图'
127 }
128
129 for (var k in items){
130 var span = document.createElement('span');
131 if (k == 'fontname' || k == 'fontsize'){
132 var select = document.createElement('select');
133 $D.addClass(select, k);
134 for (var kk in items[k]){
135 var option = new Option(kk, items[k][kk]);
136 if (!isGecko)
137 select.add(option);
138 else
139 select.appendChild(option);
140 }
141 span.appendChild(select);
142 this.toolbarItems[k] = select;
143 } else {
144 $D.addClass(span, k);
145 span.innerHTML = items[k];
146 this.toolbarItems[k] = span;
147 }
148 toolbar.appendChild(span);
149 }
150
151 $D.insertBefore(toolbar, this.iframe);
152 this.toolbar = toolbar;
153 },
154
160 _execCommand: function(sCmd, sVal){
161 this._getWin().focus();
162 this._getDoc().execCommand(sCmd, false, sVal);
163 },
164
165
169 _bindToolbarEvents: function(){
170 var _this = this,
171 items = this.toolbarItems,
172 trim = YAHOO.lang.trim;
173
174 $E.on([items['fontsize'], items['fontname']], 'change', function(e){
175 var cmd = this.className,
176 val = this.options[this.selectedIndex].value;
177 _this._execCommand(cmd, val);
178 });
179
180 $E.on(this.toolbar, 'click', function(e){
181 var t = $E.getTarget(e),
182 cmd = t.className,
183 nn = t.nodeName.toLowerCase(),
184 val = null,
185 isNeedVal = false;
186 if (nn != 'span' && !cmd) return;
187 switch (cmd){
188 case 'createlink':
189 case 'insertimage':
190 isNeedVal = true;
191 val = prompt('请输入网址:', 'http://');
192 break;
193 case 'fontname':
194 case 'fontsize':
195 return;
196 default:
197 break;
198 }
199
200 if (isNeedVal && (!val || (trim(val) == 'http://'))) return;
201 this._execCommand(cmd, val);
202
203 }, this, true);
204 },
205
206
210 _setToolbarItemUnselectable: function(){
211 function unsel(elm){
212 elm.setAttribute('unselectable', 'on');
213 }
214 unsel(this.toolbar);
215 var els = this.toolbar.getElementsByTagName('*'),
216 nn;
217 for (var i=0; i<els.length; ++i){
218 nn = els[i].nodeName;
219 if (nn && nn.toLowerCase() != 'input')
220 unsel(els[i]);
221 }
222 }
223 }
224 })();