精华内容
下载资源
问答
  • TinyMCE教程 您需要了解有关tinyMCE(或tinymice)的所有信息。 从整合开始 通过其中一项集成,快速启动TinyMCE并在您喜欢的框架中运行。 以下是选项: React 角度的 Vue JavaScript 如果选择React,请转到该。...
  • TinyMCE使用教程

    千次阅读 2018-06-14 12:04:09
    使用TinyMCE的方式主要有一下几种方式TinyMCE CloudPackage ManagersSDK / DownloadjQueryCustom Build本章主要介绍SDK一种方式,其他方式可以参考:https://www.tinymce.com/docs/get-started/advanced-install/...

    TinyMCE官方网址:https://www.tinymce.com

    使用TinyMCE的方式主要有一下几种方式

    本章主要介绍SDK一种方式,其他方式可以参考:https://www.tinymce.com/docs/get-started/advanced-install/

    一、下载官方包(地址:https://www.tinymce.com/download/)

    将下载好的压缩包解压,将解压后的文件tinymce导入需要的web项目

    二、在需要的页面导入

    	<script src="tinymce.min.js"></script>
    		<!--初始化tinymce-->
    		<script type="text/javascript">
    			tinymce.init({
    				selector: '#mytextarea',
    				language: 'zh_CN',
    				directionality: 'rtl',
    				browser_spellcheck: true,
    				contextmenu: false,
    				plugins: [
    					"advlist autolink lists link image charmap print preview anchor",
    					"searchreplace visualblocks code fullscreen",
    					"insertdatetime media table contextmenu paste imagetools wordcount",
    					"code"
    				],
    				toolbar: "insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image | code",
    
    			});
    			/*tinymce.activeEditor.uploadImages(function(success) {
    				$.post('ajax/post.do', tinymce.activeEditor.getContent()).done(function() {
    					console.log("Uploaded images and posted content as an ajax request.");
    				});
    			});*/
    		</script>

    3、在body中新建容器

    <form method="post">
         <textarea id="mytextarea"></textarea>
    </form>
    4、浏览相关页面即可


    展开全文
  • vue中使用tinymce详细教程

    千次阅读 2019-12-12 23:10:44
    貌似这篇文章帮了大家一些小忙最近tinymce出5.0版本了,下面的api还是4.x的,新版本可能会有些不适用了,最近业务繁忙,等哪天周末有时间的话我再做点更新 :) 前言 最近因业务需求在项目中嵌入了tinymce这个编辑器,...

    2019-2-18

    貌似这篇文章帮了大家一些小忙
    最近tinymce出5.0版本了,下面的api还是4.x的,新版本可能会有些不适用了,最近业务繁忙,等哪天周末有时间的话我再做点更新 :)


    前言

    最近因业务需求在项目中嵌入了tinymce这个编辑器,用于满足平台给用户编辑各类新闻内容什么的业务需求,前后也花了不少时间体验和对比了市面上各类开源编辑器。

    各大WYSIWYG编辑器的简单比较

    UEditor: 因为已经不再维护了,需要大量修改源码,很多都是专门为jsp等服务器渲染项目写的代码需要删除, 然后越删越害怕越删越不敢用,依赖jquery,需要专门用js去parse编辑完成的内容,parse完的内容还可能污染全局css,兼容老浏览器还不错, 但是,我们不怎么考虑兼容IE。所以,告辞。

    wangEditor: 中文文档,上手快,依赖jquery,功能少点要花时间去写插件,需要单独为图片上传功能写个接口,老项目忙着上线临时用过,感觉并不适合当前业务这么重的编辑功能于是放弃了。

    Quill:api友好, 功能少,需要特定的css去解析文本(这点我不大喜欢),ui好看,适合作为论坛回帖功能使用。

    CKEditor: CKEditor目前主流的还是4.x的版本,但是文档看着很瞎眼实在是提不起兴致去配置,草草用了下就放弃了,5.x版本刚从beta结束,需要指定专门的node以及npm版本,虽然功能强大配置灵活ui漂亮不过目前糟糕的兼容性基本是不可能出现在大众视野了。

    KingEditor: 丑,不喜欢,不爱用

    Draft-js: 知乎最近刚改的文本编辑器就是在draft的基础上开发的,依赖react, 弃。

    Medium-editor: 虽然看着感觉很酷炫,但是,不适合我们的业务场景啊, api也简陋可怕。

    trix: 嗯,又一个小而美,放弃

    Slatereact,放弃

    Bootstrap-wysiwygbootstrap, jquery, 放弃

    tinymce: 文档好,功能强,bug少,无外部依赖,大家用了都说好,嗯,没错就是它了。

    编辑器配置方面只要能看得懂英文耍起来还是比较简单的,适配中碰到的大部分问题都可以通过看文档解决,即便看文档解决不了网上也有大量的文章能告诉你怎么配置能解决。

    当然了,主要是我这里需要解决一些别人觉得超简单自己一想都很烦人的需求,比如:

    1. word文档粘贴进来要带格式
    2. 兼容移动端
    3. word文档粘贴进来要正常显示并且还要兼容移动端
    4. 电脑网页里粘贴进来内容要正常显示并且排版还不能乱
    5. 电脑网页拷过来的内容还要兼容到移动端

    初始化

    因为tinymce的Plugins是按需加载的
    为了能先快速上手这个编辑器
    就先在vue-cli的index.html中默认塞入一条在线cdn地址

    1. <script src="https://cdn.bootcss.com/tinymce/4.7.4/tinymce.min.js"></script>

    记得去下载语言包到本地,
    然后就在文件内引入

    import './zh_CN.js'

    后面有机会再写下单独打包的事项,毕竟这货体积还不小。

    插入vue组件模板

    1. <template>
    2. <div>
    3. <textarea :id= "Id"></textarea>
    4. </div>
    5. </template>

    记得一定要在textarea外面包一层div,不然...你自己试试看就知道了。

    组件基础配置

    将tinymce通过指定的selector挂载到组件中

    1. <template>
    2. <div>
    3. <textarea :id= "Id"></textarea>
    4. </div>
    5. </template>
    6. <script>
    7. import './zh_CN.js'
    8. export default {
    9. data () {
    10. const Id = Date.now()
    11. return {
    12. Id: Id,
    13. Editor: null,
    14. DefaultConfig: {}
    15. }
    16. },
    17. props: {
    18. value: {
    19. default: '',
    20. type: String
    21. },
    22. config: {
    23. type: Object,
    24. default: () => {
    25. return {
    26. theme: 'modern',
    27. height: 300
    28. }
    29. }
    30. }
    31. },
    32. mounted () {
    33. this.init()
    34. },
    35. beforeDestroy () {
    36. // 销毁tinymce
    37. this.$emit('on-destroy')
    38. window.tinymce.remove(`#${this.Id}`)
    39. },
    40. methods: {
    41. init () {
    42. const self = this
    43. this.Editor = window.tinymce.init({
    44. // 默认配置
    45. ...this.DefaultConfig,
    46. // prop内传入的的config
    47. ...this.config,
    48. // 挂载的DOM对象
    49. selector: `#${this.Id}`,
    50. setup: (editor) => {
    51. // 抛出 'on-ready' 事件钩子
    52. editor.on(
    53. 'init', () => {
    54. self.loading = false
    55. self.$emit('on-ready')
    56. editor.setContent(self.value)
    57. }
    58. )
    59. // 抛出 'input' 事件钩子,同步value数据
    60. editor.on(
    61. 'input change undo redo', () => {
    62. self.$emit('input', editor.getContent())
    63. }
    64. )
    65. }
    66. })
    67. }
    68. }
    69. }
    70. </script>

    好了,组件基本的初始化完成,后面正式开始踩坑之旅

    API

    具体内容看官网的API就行,英语不好的用chrome翻译下对照着demo也能看个七七八八,当然主要原因还是我比较懒。

    我这边根据自身业务需求在组件的data内写了个默认配置

    1. DefaultConfig: {
    2. // GLOBAL
    3. height: 500,
    4. theme: 'modern',
    5. menubar: false,
    6. toolbar: `styleselect | fontselect | formatselect | fontsizeselect | forecolor backcolor | bold italic underline strikethrough | image media | table | alignleft aligncenter alignright alignjustify | outdent indent | numlist bullist | preview removeformat hr | paste code link | undo redo | fullscreen `,
    7. plugins: `
    8. paste
    9. importcss
    10. image
    11. code
    12. table
    13. advlist
    14. fullscreen
    15. link
    16. media
    17. lists
    18. textcolor
    19. colorpicker
    20. hr
    21. preview
    22. `,
    23. // CONFIG
    24. forced_root_block: 'p',
    25. force_p_newlines: true,
    26. importcss_append: true,
    27. // CONFIG: ContentStyle 这块很重要, 在最后呈现的页面也要写入这个基本样式保证前后一致, `table`和`img`的问题基本就靠这个来填坑了
    28. content_style: `
    29. * { padding:0; margin:0; }
    30. html, body { height:100%; }
    31. img { max-width:100%; display:block;height:auto; }
    32. a { text-decoration: none; }
    33. iframe { width: 100%; }
    34. p { line-height:1.6; margin: 0px; }
    35. table { word-wrap:break-word; word-break:break-all; max-width:100%; border:none; border-color:#999; }
    36. .mce-object-iframe { width:100%; box-sizing:border-box; margin:0; padding:0; }
    37. ul,ol { list-style-position:inside; }
    38. `,
    39. insert_button_items: 'image link | inserttable',
    40. // CONFIG: Paste
    41. paste_retain_style_properties: 'all',
    42. paste_word_valid_elements: '*[*]', // word需要它
    43. paste_data_images: true, // 粘贴的同时能把内容里的图片自动上传,非常强力的功能
    44. paste_convert_word_fake_lists: false, // 插入word文档需要该属性
    45. paste_webkit_styles: 'all',
    46. paste_merge_formats: true,
    47. nonbreaking_force_tab: false,
    48. paste_auto_cleanup_on_paste: false,
    49. // CONFIG: Font
    50. fontsize_formats: '10px 11px 12px 14px 16px 18px 20px 24px',
    51. // CONFIG: StyleSelect
    52. style_formats: [
    53. {
    54. title: '首行缩进',
    55. block: 'p',
    56. styles: { 'text-indent': '2em' }
    57. },
    58. {
    59. title: '行高',
    60. items: [
    61. {title: '1', styles: { 'line-height': '1' }, inline: 'span'},
    62. {title: '1.5', styles: { 'line-height': '1.5' }, inline: 'span'},
    63. {title: '2', styles: { 'line-height': '2' }, inline: 'span'},
    64. {title: '2.5', styles: { 'line-height': '2.5' }, inline: 'span'},
    65. {title: '3', styles: { 'line-height': '3' }, inline: 'span'}
    66. ]
    67. }
    68. ],
    69. // FontSelect
    70. font_formats: `
    71. 微软雅黑=微软雅黑;
    72. 宋体=宋体;
    73. 黑体=黑体;
    74. 仿宋=仿宋;
    75. 楷体=楷体;
    76. 隶书=隶书;
    77. 幼圆=幼圆;
    78. Andale Mono=andale mono,times;
    79. Arial=arial, helvetica,
    80. sans-serif;
    81. Arial Black=arial black, avant garde;
    82. Book Antiqua=book antiqua,palatino;
    83. Comic Sans MS=comic sans ms,sans-serif;
    84. Courier New=courier new,courier;
    85. Georgia=georgia,palatino;
    86. Helvetica=helvetica;
    87. Impact=impact,chicago;
    88. Symbol=symbol;
    89. Tahoma=tahoma,arial,helvetica,sans-serif;
    90. Terminal=terminal,monaco;
    91. Times New Roman=times new roman,times;
    92. Trebuchet MS=trebuchet ms,geneva;
    93. Verdana=verdana,geneva;
    94. Webdings=webdings;
    95. Wingdings=wingdings,zapf dingbats`,
    96. // Tab
    97. tabfocus_elements: ':prev,:next',
    98. object_resizing: true,
    99. // Image
    100. imagetools_toolbar: 'rotateleft rotateright | flipv fliph | editimage imageoptions'
    101. }

    因为本人比较懒,以上配置导出的代码可能会有代码注入的风险,建议保存的时候再前后端都做下注入过滤,不过一般数据安全问题主要还是服务器那边的事情?。

    后面的图片上传可以单独拆出来做个小配置,直接写到props里好了。

    1. url: {
    2. default: '',
    3. type: String
    4. },
    5. accept: {
    6. default: 'image/jpeg, image/png',
    7. type: String
    8. },
    9. maxSize: {
    10. default: 2097152,
    11. type: Number
    12. },
    13. withCredentials: {
    14. default: false,
    15. type: Boolean
    16. }

    然后把这套东西塞到init配置里

    1. // 图片上传
    2. images_upload_handler: function (blobInfo, success, failure) {
    3. if (blobInfo.blob().size > self.maxSize) {
    4. failure('文件体积过大')
    5. }
    6. if (self.accept.indexOf(blobInfo.blob().type) >= 0) {
    7. uploadPic()
    8. } else {
    9. failure('图片格式错误')
    10. }
    11. function uploadPic () {
    12. const xhr = new XMLHttpRequest()
    13. const formData = new FormData()
    14. xhr.withCredentials = self.withCredentials
    15. xhr.open('POST', self.url)
    16. xhr.onload = function () {
    17. if (xhr.status !== 200) {
    18. // 抛出 'on-upload-fail' 钩子
    19. self.$emit('on-upload-fail')
    20. failure('上传失败: ' + xhr.status)
    21. return
    22. }
    23. const json = JSON.parse(xhr.responseText)
    24. // 抛出 'on-upload-success' 钩子
    25. self.$emit('on-upload-complete' , [
    26. json, success, failure
    27. ])
    28. }
    29. formData.append('file', blobInfo.blob())
    30. xhr.send(formData)
    31. }
    32. }

    至此, 一个组件的封装基本算是完成了

    看下初阶成果

    1. <template>
    2. <div>
    3. <textarea :id= "Id"></textarea>
    4. </div>
    5. </template>
    6. <script>
    7. import './zh_CN.js'
    8. export default {
    9. data () {
    10. const Id = Date.now()
    11. return {
    12. Id: Id,
    13. Editor: null,
    14. DefaultConfig: {
    15. // GLOBAL
    16. height: 500,
    17. theme: 'modern',
    18. menubar: false,
    19. toolbar: `styleselect | fontselect | formatselect | fontsizeselect | forecolor backcolor | bold italic underline strikethrough | image media | table | alignleft aligncenter alignright alignjustify | outdent indent | numlist bullist | preview removeformat hr | paste code link | undo redo | fullscreen `,
    20. plugins: `
    21. paste
    22. importcss
    23. image
    24. code
    25. table
    26. advlist
    27. fullscreen
    28. link
    29. media
    30. lists
    31. textcolor
    32. colorpicker
    33. hr
    34. preview
    35. `,
    36. // CONFIG
    37. forced_root_block: 'p',
    38. force_p_newlines: true,
    39. importcss_append: true,
    40. // CONFIG: ContentStyle 这块很重要, 在最后呈现的页面也要写入这个基本样式保证前后一致, `table`和`img`的问题基本就靠这个来填坑了
    41. content_style: `
    42. * { padding:0; margin:0; }
    43. html, body { height:100%; }
    44. img { max-width:100%; display:block;height:auto; }
    45. a { text-decoration: none; }
    46. iframe { width: 100%; }
    47. p { line-height:1.6; margin: 0px; }
    48. table { word-wrap:break-word; word-break:break-all; max-width:100%; border:none; border-color:#999; }
    49. .mce-object-iframe { width:100%; box-sizing:border-box; margin:0; padding:0; }
    50. ul,ol { list-style-position:inside; }
    51. `,
    52. insert_button_items: 'image link | inserttable',
    53. // CONFIG: Paste
    54. paste_retain_style_properties: 'all',
    55. paste_word_valid_elements: '*[*]', // word需要它
    56. paste_data_images: true, // 粘贴的同时能把内容里的图片自动上传,非常强力的功能
    57. paste_convert_word_fake_lists: false, // 插入word文档需要该属性
    58. paste_webkit_styles: 'all',
    59. paste_merge_formats: true,
    60. nonbreaking_force_tab: false,
    61. paste_auto_cleanup_on_paste: false,
    62. // CONFIG: Font
    63. fontsize_formats: '10px 11px 12px 14px 16px 18px 20px 24px',
    64. // CONFIG: StyleSelect
    65. style_formats: [
    66. {
    67. title: '首行缩进',
    68. block: 'p',
    69. styles: { 'text-indent': '2em' }
    70. },
    71. {
    72. title: '行高',
    73. items: [
    74. {title: '1', styles: { 'line-height': '1' }, inline: 'span'},
    75. {title: '1.5', styles: { 'line-height': '1.5' }, inline: 'span'},
    76. {title: '2', styles: { 'line-height': '2' }, inline: 'span'},
    77. {title: '2.5', styles: { 'line-height': '2.5' }, inline: 'span'},
    78. {title: '3', styles: { 'line-height': '3' }, inline: 'span'}
    79. ]
    80. }
    81. ],
    82. // FontSelect
    83. font_formats: `
    84. 微软雅黑=微软雅黑;
    85. 宋体=宋体;
    86. 黑体=黑体;
    87. 仿宋=仿宋;
    88. 楷体=楷体;
    89. 隶书=隶书;
    90. 幼圆=幼圆;
    91. Andale Mono=andale mono,times;
    92. Arial=arial, helvetica,
    93. sans-serif;
    94. Arial Black=arial black, avant garde;
    95. Book Antiqua=book antiqua,palatino;
    96. Comic Sans MS=comic sans ms,sans-serif;
    97. Courier New=courier new,courier;
    98. Georgia=georgia,palatino;
    99. Helvetica=helvetica;
    100. Impact=impact,chicago;
    101. Symbol=symbol;
    102. Tahoma=tahoma,arial,helvetica,sans-serif;
    103. Terminal=terminal,monaco;
    104. Times New Roman=times new roman,times;
    105. Trebuchet MS=trebuchet ms,geneva;
    106. Verdana=verdana,geneva;
    107. Webdings=webdings;
    108. Wingdings=wingdings,zapf dingbats`,
    109. // Tab
    110. tabfocus_elements: ':prev,:next',
    111. object_resizing: true,
    112. // Image
    113. imagetools_toolbar: 'rotateleft rotateright | flipv fliph | editimage imageoptions'
    114. }
    115. }
    116. },
    117. props: {
    118. value: {
    119. default: '',
    120. type: String
    121. },
    122. config: {
    123. type: Object,
    124. default: () => {
    125. return {
    126. theme: 'modern',
    127. height: 300
    128. }
    129. }
    130. },
    131. url: {
    132. default: '',
    133. type: String
    134. },
    135. accept: {
    136. default: 'image/jpeg, image/png',
    137. type: String
    138. },
    139. maxSize: {
    140. default: 2097152,
    141. type: Number
    142. },
    143. withCredentials: {
    144. default: false,
    145. type: Boolean
    146. }
    147. },
    148. mounted () {
    149. this.init()
    150. },
    151. beforeDestroy () {
    152. // 销毁tinymce
    153. this.$emit('on-destroy')
    154. window.tinymce.remove(`$#{this.Id}`)
    155. },
    156. methods: {
    157. init () {
    158. const self = this
    159. this.Editor = window.tinymce.init({
    160. // 默认配置
    161. ...this.DefaultConfig,
    162. // 图片上传
    163. images_upload_handler: function (blobInfo, success, failure) {
    164. if (blobInfo.blob().size > self.maxSize) {
    165. failure('文件体积过大')
    166. }
    167. if (self.accept.indexOf(blobInfo.blob().type) >= 0) {
    168. uploadPic()
    169. } else {
    170. failure('图片格式错误')
    171. }
    172. function uploadPic () {
    173. const xhr = new XMLHttpRequest()
    174. const formData = new FormData()
    175. xhr.withCredentials = self.withCredentials
    176. xhr.open('POST', self.url)
    177. xhr.onload = function () {
    178. if (xhr.status !== 200) {
    179. // 抛出 'on-upload-fail' 钩子
    180. self.$emit('on-upload-fail')
    181. failure('上传失败: ' + xhr.status)
    182. return
    183. }
    184. const json = JSON.parse(xhr.responseText)
    185. // 抛出 'on-upload-complete' 钩子
    186. self.$emit('on-upload-complete' , [
    187. json, success, failure
    188. ])
    189. }
    190. formData.append('file', blobInfo.blob())
    191. xhr.send(formData)
    192. }
    193. },
    194. // prop内传入的的config
    195. ...this.config,
    196. // 挂载的DOM对象
    197. selector: `#${this.Id}`,
    198. setup: (editor) => {
    199. // 抛出 'on-ready' 事件钩子
    200. editor.on(
    201. 'init', () => {
    202. self.loading = false
    203. self.$emit('on-ready')
    204. editor.setContent(self.value)
    205. }
    206. )
    207. // 抛出 'input' 事件钩子,同步value数据
    208. editor.on(
    209. 'input change undo redo', () => {
    210. self.$emit('input', editor.getContent())
    211. }
    212. )
    213. }
    214. })
    215. }
    216. }
    217. }
    218. </script>

    直接引入组件调用就行了

    1. <template>
    2. <mce-editor
    3. :config = "Config"
    4. v-model = "Value"
    5. :url = "Url"
    6. :max-size = "MaxSize"
    7. :accept = "Accept"
    8. :with-credentials = false
    9. @on-ready = "onEditorReady"
    10. @on-destroy = "onEditorDestroy"
    11. @on-upload-success= "onEditorUploadComplete"
    12. @on-upload-fail = "onEditorUploadFail"
    13. ></mce-editor>
    14. </template>

    但是作为一名优秀的程序员,这怎么可能够嘛。
    下面说下打包的事情

    塞入webpack

    为了加快页面载入速度就要首先解决载入文件过多的问题,而大部分时间用户并不需要每次打开页面都先加载一遍editor的核心文件,而editor本身也要按需加载内容,一开始想把每个plugin都搞成独立组件模块按需载入,但是这就要涉及到修改编辑器本身源码,或者说对window.tinymce删掉点特性,这些都太麻烦也都有风险,对后面的代码维护影响也大,索性就都先留着。
    后面边做边改吧

    还是以vue-cli为例
    把官网下载的包塞到stataic文件夹中
    然后删掉index.html模版中的cdn代码吧不需要了
    当然这里有俩选择
    要么做成一个异步组件,单独打包,按需载入
    要么直接引入到main.js中将包打成为一个巨无霸
    所以我选择前者,

    首先老规矩 引入编辑器主体

    import '../../static/tinymce/tinymce.min.js'

    然后刷新下页面,不出意外应该是报这么个错Uncaught SyntaxError: Unexpected token <
    眼尖的朋友应该知道是怎么回事了theme.js:1
    在默认配置下, tinymce载入的theme的路径居然是这个
    Request URL:http://localhost:8080/themes/modern/theme.js
    然后我跑去官网搜了下api 只搜到一个叫document_base_url的api,但是根据多年程序员的直觉经验告诉我 不是这货(嗯,我在这里卡住了),网上翻了下各地文献,都没有啊,
    那怎么办呢
    于是我就跑去看源码...但是4万行...算了...
    然后我就在控台打印了下tinymce对象,然后发现了一个叫baseURLstring对象,嗯,有希望了。
    在源码里搜了下baseURL
    蹦出来这段代码 .... 算了有很多段...
    大致思想就是通过当前URI拆出来个baseURL,改掉就行了

    window.tinymce.baseURL = '/static/tinymce'

    如果需要载入的地址是另一个比如自己公司的cdn的路径,那改成全路径就行了

    window.tinymce.baseURL = 'http://cdn.xxx.com/static/tinymce'

    貌似路径的问题解决了

    但是新的问题又出现了,
    插件下过来都是带min的,但默认载入的插件都是不带min的,一定是我源码没看仔细,
    然后我又搜了一下代码

    1. if (!baseURL && document.currentScript) {
    2. src = document.currentScript.src;
    3. if (src.indexOf('.min') != -1) {
    4. suffix = '.min';
    5. }
    6. baseURL = src.substring(0, src.lastIndexOf('/'));
    7. }

    希望就在眼前,貌似是业务我载入的方式是直接导入到模块的,于是一个叫suffix的默认值为空了,于是我去又加了行代码:

    window.tinymce.suffix = '.min'

    成功!
    你看嘛,超级简单的是不是,根本不用改源码,网上说的动不动就去改源码什么的不要信啊不要信,大部分面向对象的事情改个默认值就行了。

    对了,还记得前面的语言包嘛,
    下过来塞到/static/tinymce/langs文件夹里
    然后删掉

    import './zh_CN.js'

    这行代码
    DefaultConfig中放入一个新配置项

    language: 'zh_CN'

    好了,后面就是模块打包的事情了,

    打包

    前面打的包有一个问题是默认配置是载入tinyMce本体,那么就会造成这个包大概有500k的体积,如果这个组件不做异步载入的处理,那么对于某些业务来说就是灾难。虽然这么做打开只用载入一个文件,业务比较稳定。
    但我觉得这样不优雅所以最后还是把它单独拎出来了。
    同理,根据这个库本身的特性,我们完全可以把这么多个必须的plugin按需要直接统一打成一个包,直接载入。这样,我们就又多了一个几百k的plugins包。
    然后把plugins包和tinyMce主体包在不阻塞页面加载的情况下,做个懒加载提前缓存好文件方便后面使用,而组件本身在挂载前做个监听window.tinymce全局变量的方法,然后cdn控制下文件的过期时间即可。
    这样,在保证了灵活度的前提下也保证了业务载入的速度。

    完,感谢阅读。

    展开全文
  • 富文本编辑器TinyMCE菜鸟使用教程

    千次阅读 2019-04-09 18:50:42
    老师给我了一个Ckeditor,个人感觉比较丑,(主要是老师没有给使用文档,我作为一个完完全全的小菜鸟,根本不会使),我就从网上找好看并且好用的富文本编辑器,TinyMCE就是最佳的选择。 我后台...

    系统:windows10

    工具:Visual Studio 2017

    语言:C#

    我正在做毕设,需要保存信息,直接保存到数据库的文本没有格式,问过老师之后明白需要使用富文本编辑器接收信息,然后存入数据库。老师给我了一个Ckeditor,个人感觉比较丑,(主要是老师没有给使用文档,我作为一个完完全全的小菜鸟,根本不会使),我就从网上找好看并且好用的富文本编辑器,TinyMCE就是最佳的选择。

    我后台使用的是一般处理程序。
    我们先来看一下TinyMCE的效果图
    在这里插入图片描述
    个人感觉还是比较好看的。现在给大家讲如何使用。

    首先,你需要进入TinyMCE官网免费注册一下,得到一个免费的Key,如图

    TinyMCE官网:Tiny官网

    原装的富文本编辑器是英文的,如果你想使用中文的话,请点击Language Packages | TinyMCE这里,下载对应语言的js文件。
    下载成功后,把文件解压,放在langs/…文件夹中,把文件夹放入解决方案。
    在这里插入图片描述

    然后在前端,html页面,<head></head>中间,引入.

    代码1

    <script src="https://cloud.tinymce.com/5/tinymce.min.js?apiKey=这里放入你注册时,系统分配给你的Key"></script>
    
    <script src="../langs/zh_CN.js"></script>
    

    而后继续添加

    代码2

    <script type="text/javascript">   
    
         tinymce.init({        
    
            selector: 'textarea',        
    
            language: 'zh_CN',   
    
         });
    
    </script>
    

    此时引用结束。现在在正文<body></body>中你理想的位置,添加一下代码

    代码3

    <form method="post">
    
        <textarea id="mytextarea">Hello, World!</textarea> 
    
    </form>
    

    现在大体结构已经完成,看一下成果吧

    在这里插入图片描述

    如图!这就是成果。

    如果你不想要“文件”那一栏,就在代码2中,添加这句话

    menubar: false,
    

    如果不想要“加粗”那一栏,就在代码2中,添加这句话

    toolbar: false,
    

    想要在后台接受富文本编辑器中内容,则需要把 <textarea id="mytextarea">Hello, World!</textarea> 添加name属性,然后在后台接受

    例如我的代码为

    <textarea id="mytextarea" name="content">Hello, World!</textarea> 
    

    使用string content=context.Request["content"];来接收文本即可。

    以下就是Tiny简单实用办法

    不过,我在使用的时候,后台使用string接受富文本编辑器中内容时,出现一个问题,如图

    这个时候需要在Web.config<system.web></system.web>标签中,添加

    <pages validateRequest="false" />
    

    <httpRuntime targetFramework="4.6.1"/>中添加

    requestValidationMode=“2.0”

    成为

    <httpRuntime targetFramework="4.6.1" requestValidationMode="2.0" /> 
    

    即可!

    新手小白,如果有不对的,还请大佬指教!,如果有人有对一般处理程序感兴趣的话,也可以关注我微信公众号:Wuluo_97 大家一起探讨鸭!

    展开全文
  • html编辑器tinymce使用配置教程实例demo分享 源代码教程地址:http://www.zuidaima.com/share/1550463284202496.htm

    原文:html编辑器tinymce使用配置教程实例demo分享 源代码教程地址:http://www.zuidaima.com/share/1550463284202496.htm

    很简单的demo,大家可以扩展,不过功能很全。

    标签: 编辑器 富文本 html tinymce 教程话题: 前端技术 入门教程

    展开全文
  • 教程假定您已经构建了PHP多语言站点/框架,并且您(无论管理员是谁)都希望TinyMCE自动切换到站点的当前语言。 一个实际的例子是:您刚刚将站点的界面切换为西班牙语,但是您意识到编辑器的界面仍然是英语,而您...
  • https://liub37.com/vue-tinymce-5.html
  • 本文将罗列草图工作台可见的重点工具条及命令,分为两个部分:一、通用工具栏二、草图工作台工具栏为了方便大家学习,同时罗列命令的中英文含义。时间和精力关系,具体命令留在后续详细讲解。一、通用工作栏1.1 标准...
  • tinymce富文本使用记录

    2020-12-30 17:07:43
    首先按照网上的教程,在static静态文件夹里新建tinymce,按照网上的教程做就可以。查看链接 这里说一下,当时我下载的@tinymce/tinymce-vue是4.0.0的tinymce是5.6.2的,但是用不了,报错, 具体报错不记得了,当时...
  • Tinymce:从入门到进阶

    2020-06-25 17:57:03
    目前互联网上关于tinymce教程,内容都与该篇基础使用教程类似。但这些文章对于一些使用细节都没有进行深入的解释,故作此文。 相关资料站 一个文档汉化站,资料较为全面,除极少数未更新部分 官网文档站 官方语言...
  • 注明:是教程仅适用于 Tinymce 4.x,版本5.x以上不支持 优点: 1. 唯一一个从 word 粘贴过来还能保持绝大部分格式的编辑器; 2. 不需要找后端人员扫码改接口,前后端分离; 缺点: 1.图片上传只能上传url,需要...
  • 如何动态定位TinyMCE

    2013-11-29 00:00:00
    问题 本教程假设你已经建立了一个PHP语言网站/框架和你,或谁的管理是,想TinyMCE的自动切换到你的网站的当前语言。 一个实际的例子是:你刚刚打开你的网站的界面为西班牙语,但你知道编辑器的界面仍为英文,你想它...
  • vue+tinymce5 富文本编辑器使用、踩坑

    千次阅读 2020-08-06 14:22:30
    注:此教程适用于 tinymce 5.x 版本(如果是tinymce 4.x,则可能不会实现 ) 安装与配置操作 (1)安装 npm install -s @tinymce/tinymce-vue npm install -s tinymce (2)在node_modules找到...
  • React版TinyMCE富文本中文教程 写在前面:因为公司项目的需要,需要寻找一款免费,开源,功能强大的富文本用作自定义打印。公司的前端框架用的是React,所以需求就很明显,要支持框架,开源,功能强大。 经过仔细...
  • 大多数网络教程对于tinymce在django中的配置都可能出现此种错误,网络上对于本问题并没有正确的的解决方案,故做此记录。
  • Ext 整合富文本编辑器Tinymce插件

    千次阅读 2017-09-25 15:29:15
    手头有个项目需要做一个富文本编辑器,Ext自带的文本编辑器htmleditor功能不齐全,上网搜了很多资料,都是提供部分代码,研究了下,终于搞出来了,贴出教程供自己查看和别人借阅。 下载插件tinymce (中文版版本)...
  • 特别是cms类的开发,说到富文本编辑器,其中有一款富文本编辑器tinymce在Github中的star很多,国内有用到的小伙伴可以关注一下,社区有中文文档做的很棒,这里赞一下,但是不是最新,网上关于tinymce的使用教程也很...
  • 有时候用的是UEditor,有时候用的CKEditor,KindEditor,TinyMCE。 在网上查了很多资料,UEditor和其它的Web编辑器(富文本编辑器)在Chrome中可以支持单张图片粘贴。但是我们的用户需要处理的是Word中的图片和文字,...
  • tinymce是一款综合口碑特别好、功能异常强大... 本人不认为配置tinymce需要如此复杂,并认为很多教程的一些步骤是完全冗余的,因此重新参考官方教程,反复实践,终究得以攻克。现将配置的细节、一些极其关键的要...
  • 不确定能否上链接,带附件...接下来全面进入VBA及case,教程只有少量简单易懂的了,而case都是追求0培训直接应用款。功能除去ALT+F8直接调用sub命名的宏外,private sub的"隐私"宏前台看不到,需要其他方式设置好调...
  • 这一点国内还真没有什么介绍类的文章,所以我到pligg官网上看过来的英文教程翻译给大家,希望对大家有所帮助: 我们要使用HTML编辑器而不是pligg默认的那个比较单调的纯文本编辑器,就需要用到一个叫做tinyMCE的程序...
  • 博客园美化教程总结

    2018-05-03 13:22:00
    写在前面 本文中提到的部分设置需要 JS 权限,因此进行相关更改的时候,请确保有 JS 权限。...以下给出几种设置代码高亮的方式,讨论的编辑器仅在 TinyMCE 和 Markdown 进行过实验,其他编辑器可自行...

空空如也

空空如也

1 2 3
收藏数 42
精华内容 16
关键字:

tinymce教程