群组功能发帖时候增加编辑器,其实并不是很复杂,只不过我们要理解,为什么要这样修改代码。
*可能有些听不懂,不过不会影响修改,多学点东西总是好的吧?
首先,我们解析一下blog的编辑器。
看模板文件夹下cp_blog.htm里面的这段代码:
代码:
代码
<
textarea
class
=”userData”
name
=”message”
id
=”uchome-ttHtmlEditor”
style
=”height:100%;width:100%;display:none;border:0px”
>
$blog[message]
</
textarea
>
<
iframe
src
=”editor.php?charset=$_SC[charset]&allowhtml=$allowhtml”
name
=”uchome-ifrHtmlEditor”
id
=”uchome-ifrHtmlEditor”
scrolling
=”no”
border
=”0″
frameborder
=”0″
style
=”width:100%;border:
1px solid #C5C5C5;” height
=”400″
></
iframe
>
第一步呢,我们先要读懂这两行代码:
这就是编辑器的比较核心的部分,用一个隐藏的textarea来提交信息,用js提取框架iframe里面的编辑内容,而iframe里面的部分是编辑器页面。
display:none 表示用css隐藏了textarea,看不到但是提交信息是可以发出去的。
我们会发现,textarea的iduchome-ttHtmlEditor和iframe里面的name和id都很像,对,这两个能合并在一起就是用这个挂钩的,当然,还要借助于js实现。
第二步,再看提交的时候,触发了什么,请看这两段代码,还是那个文件。
代码:
<
input
type
=”button”
id
=”blogbutton”
name
=”blogbutton”
value
=”提交发布”
onclick
=”validate(this);”
style
=”display:
none;”
/>
代码:
<
input
type
=”button”
id
=”issuance”
onclick
=”document.getElementById(’blogbutton’).click();”
value
=”保存发布”
class
=”submit”
/>
如果刚才认真听课的同学都发现了,“display: none”又一次使用到了隐藏。
但是提交的时候更有趣:
下面的按钮触发的是上面按钮的动作,怎么做到的呢?
代码:
onclick
=
”document.getElementById(’blogbutton’).click();”
这行代码表示在点击的时候,触发一个js事件:document.getElementById(’blogbutton’).click();
而这个事件的js实际上就是点击第一个按钮的动作,等同于触发了第一个按钮的:
代码:
onclick
=
”validate(
this
);”
这个部分,那么我们就找到了提交的时候,一定会包含处理编辑器的js函数:validate
搜索刚才那个文件中的代码,我们很容易找到这段:
代码:
代码
1
function
validate(obj) {
2
3
var
subject
=
$(’subject’);
4
5
if
(subject) {
6
7
var
slen
=
strlen(subject.value);
8
9
if
(slen
<
1
||
slen
>
80
) {
10
11
alert(”标题长度(
1
~
80字符)不符合要求”);
12
13
subject.focus();
14
15
return
false
;
16
17
}
18
19
}
20
21
22
23
if
($(’seccode’)) {
24
25
var
code
=
$(’seccode’).value;
26
27
var
x
=
new
Ajax();
28
29
x.get(’cp.php
?
ac
=
common
&
op
=
seccode
&
code
=
’
+
code,
function
(s){
30
31
s
=
trim(s);
32
33
if
(s
!=
’succeed’) {
34
35
alert(s);
36
37
$(’seccode’).focus();
38
39
return
false
;
40
41
}
else
{
42
43
uploadEdit(obj);
44
45
return
true
;
46
47
}
48
49
});
50
51
}
else
{
52
53
uploadEdit(obj);
54
55
return
true
;
56
57
}
58
59
}
60
61
这个东西什么意思呢?我们大概看看,我也作简要解释:
function是函数必须的部分,后面表示 validate(obj)函数名和所传递进来的参数。参数是一个对象,所以用obj来命名,不是语法必须,只是比较方便理解。
然后定义了另外一个对象,在函数内部: var subject = $(’subject’);
表示将id为’subject’的部分当作对象给前面的变量,听不懂这些术语没所谓,以后会明白,不会影响这次你学习哦。
有这样的对象有啥用啊?
这样的对象可以直接指向某个DOM的节点,更简单的说法是方便操作部分指定的html,哈哈,这样理解了吧?
再看这个js函数。我用注释来说明每一行做什么:
代码:
代码
1
function
validate(obj) {
//
创建函数和函数名,声明需要传入什么参数
2
3
var
subject
=
$(’subject’);
//
设定一个函数内的变量,方便后面用,指向了id为subject的html部分。
4
5
if
(subject) {
//
如果有这个对象,可以理解成,如果有这个html的话
6
7
var
slen
=
strlen(subject.value);
//
读取这个html部分的value值的长度
8
9
if
(slen
<
1
||
slen
>
80
) {
//
判断长度是否超过80或者小于1.
10
11
alert(”标题长度(
1
~
80字符)不符合要求”);
//
提示不合法
12
13
subject.focus();
//
将光标焦点放到指定的对象上
14
15
return
false
;
//
返回这个函数的返回值为否(假),目的是告诉浏览器不要继续表单提交了,有问题啦。如果运行到这里,整个函数结束,不再继续运行。但是,刚才的判断部分如果没有进入这个大括号的话,程序继续运行。细节部分参考一下相关描述js函数的书籍或资料,不详细说了。
16
17
}
18
19
}
20
21
22
23
if
($(’seccode’)) {
//
这个是判断’seccode’部分的,有ajax的部分,跳过大部分,我只简单说,我们直接谈中心部分。
24
25
var
code
=
$(’seccode’).value;
//
读取’seccode’的值
26
27
var
x
=
new
Ajax();
//
创建一个ajax的实例,理解为要做ajax之前的热身,不然程序容易抽筋,那就不能继续了,呵呵
28
29
x.get(’cp.php
?
ac
=
common
&
op
=
seccode
&
code
=
’
+
code,
function
(s){
//
将’cp.php?ac=common&op=seccode&code=’ + code作为ajax异步传输读取的地址,返回的是这个地址给的结果,也就是s
30
31
s
=
trim(s);
//
安全处理s
32
33
if
(s
!=
’succeed’) {
//
如果s不是’succeed’的话,则运行下面的部分。
34
35
alert(s);
//
警告,内容就是s,估计如果s不是’succeed’的话,会直接返回错误提示。
36
37
$(’seccode’).focus();
//
呵呵,上面见过,将鼠标光标放到’seccode’上。
38
39
return
false
;
//
返回别继续的指令,刚才说过。
40
41
}
else
{
//
否则运行(也就是说s的内容就是’succeed’)
42
43
uploadEdit(obj);
//
哈哈,bingo~~~就是要照这个,更新编辑器的函数
44
45
return
true
;
//
告诉浏览器,哈哈,正确了,提交吧,我拿到了编辑器的数据啦~~~
46
47
}
48
49
});
50
51
}
else
{
//
这两行自己理解一下,自己看看括号是哪里的if和else,如果不知道if-else是什么,参考我之前发过的教程。
52
53
uploadEdit(obj);
54
55
return
true
;
56
57
}
58
59
}
60
61
这样我们就找到要得部分了,估计现在有些朋友会晕了,“改一个编辑器这么麻烦啊?”
是啊,如果你熟练的话,其实也不会特别麻烦,所以提醒某些喜欢免费的朋友,无论大家分享什么东西,都要懂得感恩,很多细节的部分你是看不到的,但是很有可能人家用心坐了很久,扯远了,我们继续哦
找到刚才那个地方,也就是uploadEdit(obj);
这还不够,你并不了解他具体是怎么运行的,确认一下,看看他在那里呢?
找了这个文件没有发现声明这个函数的部分,也就是没有找到 function uploadEdit
再看看代码,发现这个:
代码:
<
script
language
=”javascript”
src
=”image/editor/editor_function.js”
></
script
>
*html中包含js的一种方法,具体参考html相关书籍和资料
好,开心吧,为什么呢?因为这个就是编辑器js的函数集文件了,马上打开看看吧,很快找到(第一个函数就是啊):
代码:
代码
function
uploadEdit(obj) {
mainForm
=
obj.form;
forms
=
$(’attachbody’).getElementsByTagName(”FORM”);
albumid
=
$(’uploadalbum’).value;
edit_save();
upload();
}
edit_save();???这个就是保存编辑器内容的东西吧,答对,加十分,哈哈
我们拿出来这个函数直接用,因为刚才那个文件已经引用过这个文件了,也就是刚才那句代码:
代码:
<
script
language
=”javascript”
src
=”image/editor/editor_function.js”
></
script
>
怎么直接用,估计你也会了,复制,粘贴呗……
返回cp_blog.htm文件,我们再次理顺这个流程,我考虑将具体代码修改部分留给各位朋友,多测试,一定会有人做出来的,并不是很难。
编辑器运行的过程是这样的:
1、用户首先在这部分使用编辑器输入了想要的内容,编辑器直接呈现了效果,但是资料还是在iframe里面,没有传送到textarea部分:
代码:
代码
<
textarea
class
=”userData”
name
=”message”
id
=”uchome-ttHtmlEditor”
style
=”height:100%;width:100%;display:none;border:0px”
>
$blog[message]
</
textarea
>
<
iframe
src
=”editor.php?charset=$_SC[charset]&allowhtml=$allowhtml”
name
=”uchome-ifrHtmlEditor”
id
=”uchome-ifrHtmlEditor”
scrolling
=”no”
border
=”0″
frameborder
=”0″
style
=”width:100%;border:
1px solid #C5C5C5;” height
=”400″
></
iframe
>
2、用户继续编辑其他的部分,当要提交的时候,用一个隐藏按钮提交内容:
代码:
<
input
type
=”button”
id
=”blogbutton”
name
=”blogbutton”
value
=”提交发布”
onclick
=”validate(this);”
style
=”display:
none;”
/>
代码:
<
input
type
=”button”
id
=”issuance”
onclick
=”document.getElementById(’blogbutton’).click();”
value
=”保存发布”
class
=”submit”
/>
3、触发了js函数validate,这个函数又一次触发了编辑器更新的函数uploadEdit。
代码:
代码
1
function
validate(obj) {
//
创建函数和函数名,声明需要传入什么参数
2
3
var
subject
=
$(’subject’);
//
设定一个函数内的变量,方便后面用,指向了id为subject的html部分。
4
5
if
(subject) {
//
如果有这个对象,可以理解成,如果有这个html的话
6
7
var
slen
=
strlen(subject.value);
//
读取这个html部分的value值的长度
8
9
if
(slen
<
1
||
slen
>
80
) {
//
判断长度是否超过80或者小于1.
10
11
alert(”标题长度(
1
~
80字符)不符合要求”);
//
提示不合法
12
13
subject.focus();
//
将光标焦点放到指定的对象上
14
15
return
false
;
//
返回这个函数的返回值为否(假),目的是告诉浏览器不要继续表单提交了,有问题啦。如果运行到这里,整个函数结束,不再继续运行。但是,刚才的判断部分如果没有进入这个大括号的话,程序继续运行。细节部分参考一下相关描述js函数的书籍或资料,不详细说了。
16
17
}
18
19
}
20
21
22
23
if
($(’seccode’)) {
//
这个是判断’seccode’部分的,有ajax的部分,跳过大部分,我只简单说,我们直接谈中心部分。
24
25
var
code
=
$(’seccode’).value;
//
读取’seccode’的值
26
27
var
x
=
new
Ajax();
//
创建一个ajax的实例,理解为要做ajax之前的热身,不然程序容易抽筋,那就不能继续了,呵呵
28
29
x.get(’cp.php
?
ac
=
common
&
op
=
seccode
&
code
=
’
+
code,
function
(s){
//
将’cp.php?ac=common&op=seccode&code=’ + code作为ajax异步传输读取的地址,返回的是这个地址给的结果,也就是s
30
31
s
=
trim(s);
//
安全处理s
32
33
if
(s
!=
’succeed’) {
//
如果s不是’succeed’的话,则运行下面的部分。
34
35
alert(s);
//
警告,内容就是s,估计如果s不是’succeed’的话,会直接返回错误提示。
36
37
$(’seccode’).focus();
//
呵呵,上面见过,将鼠标光标放到’seccode’上。
38
39
return
false
;
//
返回别继续的指令,刚才说过。
40
41
}
else
{
//
否则运行(也就是说s的内容就是’succeed’)
42
43
uploadEdit(obj);
//
哈哈,bingo~~~就是要照这个,更新编辑器的函数
44
45
return
true
;
//
告诉浏览器,哈哈,正确了,提交吧,我拿到了编辑器的数据啦~~~
46
47
}
48
49
});
50
51
}
else
{
//
这两行自己理解一下,自己看看括号是哪里的if和else,如果不知道if-else是什么,参考我之前发过的教程。
52
53
uploadEdit(obj);
54
55
return
true
;
56
57
}
58
59
}
60
4、我们追寻找到那个函数,终于了解,最终更新编辑器的中心函数是edit_save();
代码:
<
script
language
=”javascript”
src
=”image/editor/editor_function.js”
></
script
>
代码:
代码
1
function
uploadEdit(obj) {
2
3
mainForm
=
obj.form;
4
5
forms
=
$(’attachbody’).getElementsByTagName(”FORM”);
6
7
albumid
=
$(’uploadalbum’).value;
8
9
edit_save();
10
11
upload();
12
13
}
14
我们知道了这些,就可以照猫画虎的制作出来任何地方的编辑器了。
附加解释一下edit_save()的内部结构,有朋友可能会问到,还是用注释来解释(之前讲过的部分就不说了,仔细看着个帖子就好):
代码:
代码
1
//
提交保存
2
3
function
edit_save() {
4
5
var
p
=
window.frames[
'
uchome-ifrHtmlEditor
'
];
//
见下一行
6
7
var
obj
=
p.window.frames[
'
HtmlEditor
'
];
//
和上面那句代码一起创建一个对象,指向了’uchome-ifrHtmlEditor’部分
8
9
var
status
=
p.document.getElementById(’uchome
-
editstatus’).value;
//
读取了’uchome-ifrHtmlEditor’内’uchome-editstatus’部分的值,用返回值来继续下面的判断
10
11
if
(status
==
‘code’) {
//
如果是code的话(英汉字典:code=代码)
12
13
$(’uchome
-
ttHtmlEditor’).value
=
p.document.getElementById(’sourceEditor’).value;
//
将html(也就是编辑器内生成的html)写入那个id为’uchome-ttHtmlEditor’的textarea内部,这样的话,提交表单就不是空值了
14
15
}
else
if
(status
==
‘text’) {
//
如果是text的话(英汉字典:text=文本)
16
17
if
(is_ie) {
//
如果在ie浏览器下,这个is_ie是这个js的全局变量,是有其他代码判断后生成的,不是js语言内置的,这里可能会有朋友乱用,说明一下
18
19
obj.document.body.innerText
=
p.document.getElementById(’dvtext’).value;
20
21
$(’uchome
-
ttHtmlEditor’).value
=
obj.document.body.innerHTML;
//
这两句都是将文本写入指定区域
22
23
}
else
{
//
如果是其他浏览器
24
25
obj.document.body.textContent
=
p.document.getElementById(’dvtext’).value;
26
27
var
sOutText
=
obj.document.body.innerHTML;
28
29
$(’uchome
-
ttHtmlEditor’).value
=
sOutText.replace(
/
\r\n|\n
/
g,”
<
br
>
”);
//
类似上面的,将文本写入指定区域
30
31
}
//
这两个不同的部分很典型的体现了js需要写出来不同浏览器兼容的代码,并不是在ie下成功,就在任何地方运行成功,这个是做产品时候的细节部分,也是最基本的,其实很多时候程序是否好坏,这些细节地方体现的最多,但是不用到这里你看不出来开发者的功力,虽然只是一个非常基本和初级的地方,我也想这样拓展说一下,做出来一个功能其实并不是很难,麻烦的是后期测试和修改bug时候,有时候开发时间如果是10的话,测试和后期整理代码要到30,这样1比3的比例和一般人想象还是有出入的。
32
33
}
else
{
//
如果是其他类新,则直接写入
34
35
$(’uchome
-
ttHtmlEditor’).value
=
obj.document.body.innerHTML;
//
参考前面注释:写入值
36
37
}
38
39
backupContent($(’uchome
-
ttHtmlEditor’).value);
//
这个是方便下次恢复数据的代码。
40
41
}
42
43
好了,整理了半天,希望对各位有所帮助。