请选择 进入手机版 | 继续访问电脑版

技能趴

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 156|回复: 0

[Discuz二次开发资料] discuz编辑器二次开发浅析 参考文档

[复制链接]

107

主题

273

帖子

4

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
4
发表于 2018-10-28 11:18:24 | 显示全部楼层 |阅读模式
一、获取编辑器代码:
          通过最简单的方法(看PHP代码的话会SI人的),直接打开网页,把HTML代码拿下来了,并且把CSS,JS都移出来了.通过筛选,把需要的JS都拿了.

二、粗略看一看HTML代码:
          基本把结构看通了,把我暂时不需要的删掉了.然后把结构基本看通了..是表格里加DIV结构.但有个奇怪的地方..怎么字体,大小那些弹出框是一个TR里面的东西呢?它怎么恢复数据的呢..最大问题..怎么在HTML页面上好似在文本框里编辑一样呢..种种问题漂浮在脑里..

三、JS代码入口寻找
           究竟是哪个入口函数把弹出框的动作绑定的?要找它出来!
           经过寻找..发现了editor.js里的第一个函数,newEditor(mode, initialtext),未清楚其参数用法..继续探究中..
    突然发现了奇怪的符号$(),里面输入的是ID号。。很奇怪。。难道是某个JAVASCRIPT的特别处理方法?找了老半天。。原来是个函数。。function $(id){return document.getElementById(id);}晕!。。

四、研究一个简单的流程:(从点击BOLD到出现改变)[仅在TEXT中,还没研究HTML页的编辑器]
    参数:wysiwyg-->0时表示TEXT表示,1时表示HTML文本编辑,现讨论流程为wysiwyg=0
    1)newEditor:
  载入页面,程序执行editor.js里的newEditor(wysiwyg),传入参数为0,代表采用源码编辑器.
  函数修改CSS,改变效果从而显示焦点在源码编辑器
     判断函数是否有保存记录(功能还没知怎么实现),有的话就执行writeEditorContents(initialtext);
  addSnapshot(textobj.value);和setEditorEvents();还没知道干啥的。。
  进入initEditor();
    2)initEditor:
  获取所有button里的a标签,对cmd类和popup类进行绑定事件,由于bold是属于cmd类,从而进入cmd的绑定事件discuzcode
  到了dicuzcode里,很长,很累赘,但其实只要看条件,就会发现bold是最后那里。。从而马上进入另一个方法applyFormat(cmd, false, (isUndefined(arg) ? true : arg))
     3)applyFormat:
  这里有个函数,虽然因为进不去,execCommand,什么东西?由于这里也是没什么好说的。。看条件马上又跳到下一个函数。。wrapTags(cmd.substr(0, 1), false);
    4)wrapTags:
  这里进行一些字符串处理,拼凑一些discuzcode,主要是获取选中文本,它这里用了一个很简单的句就获取了:var selection = getSel();
  生成了更换后的字符号并储存到text中,然后就到下一个方法:insertText(text, strlen(opentag), strlen(closetag), in_array(tagname, ['code', 'quote', 'free', 'hide']) ? true : false);
    5)insertText:
  到了这里需要测试条件,因为还没知道条件是什么意思,所以到了if(document.selection && document.selection.createRange)下面
  通过sel = document.selection.createRange();生成一个选取块,然后把选取块的文本给了sel.text,应该就是选中的文本,然后sel.MoveStart和sel.MoveEnd使选中矩阵选中开始到结束的地方。在用sel.select()选中文本.

对这个简单过程的分析:
主要问题是如何获取选择的区域,如果改变选择区域是这里的关键问题。下一步要分析这个问题。

五、从上面可知,获取选择的主要函数是getSel(),下面将分析getSel()
原来是范围对象弄的。。(可恨当初我没仔细看书。。),只要用document.selection.createRange()创建一个范围,然后就能获取它的text,即document.selection.createRange().text。获取后,再通过moveStart和moveEnd选取对象范围。再进行改变值,最后用一个select()方法选中对象即可。。

六、接下来,要看看它是如何达到数据储存功能的。
首先,经过测试,发现不是文本添加过程中把数据放进缓冲的,那么估计应该是TEXT的onchange事件吧。
几经波折,通过多种常识..终于发现了储存机制的关键所在..原来是利用了ie的userdata机制和firefox的sessionStorage进行储存.
在post.js下,有一个事件,那就是伟大的window.onbeforeunload事件.对了!就是这个事件,然后对数据进行储存!
储存方法其实很简单..就是先获取数据,然后采用uesrdata或sessionStorage方法储存数据!储存量竟可达640KB..什么概念!
储存时,只需要设置一个标记,然后在载入时读取该储存控件的标记数据即可.储存格式为XML,这样更好.
七、转换discuz代码
这里就无需多提了,都在bbcode.js里的bbcode2html方法里了。只是想提提这个方法就是转换方法。
八、所见即所得模式
下面从按钮发生onclick事件说说其流程吧
1)onclick事件向editor.js里的switchEditor函数发送数据,即wysiwyg。当点"所见"模式时,wysiwyg=1
2)switchEditor:
  通过getEditorContents()函数,获取现在的文本,然后把它转换成html.
  再运行newEditor方法,输入参数为(wysiwyg,parsedtext);
3)newEditor(wysiwyg,parsedtext):
  创建iframe,让editwin = editbox.contentWindow;(关键)editdoc = editwin.document;运行writeEditorContents方法.setEditorEvents方法和initEditor方法
4)writeEditorContents(isUndefined(initialtext) ?  textobj.value : initialtext):
  实现HTML编写方法,关键一点就是iframe的特性,要实现iframe能像text一样编辑,只需要加以下属性:
  editdoc.designMode = 'on';设置了这点,马上iframe变成文本编辑器。
  不过对于FF,要兼容的话这样是不够的,所以在newEditor上面就设置了contentWindow,在FF下,只有在iframe.contentWindow.body下设置才能有效。最后设置editdoc.open('text/html', 'replace');editdoc.write(text); editdoc.close(); 这个来写入数据。至于editdoc.body.contentEditable = true;这个可能是处于对兼容问题的更大支持而写的吧。然后再处理些CSS问题,解决,一个新的编辑器,所见即所得编辑器,出来了。
5)改变后,再处理一下setEditorEvent,和initEditor,就和原来的差不多了。不过变成HTML编辑器后,编辑方面更快捷了,不要考虑字符的变化,只需要用execCommand来改变即可。
---------------------
游客,如果您要查看本帖隐藏内容请回复


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|技能趴

GMT+8, 2018-12-17 13:22 , Processed in 0.079551 second(s), 31 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表