1.快速集成

快速集成部分參考tiny中文文檔 http://tinymce.ax-z.cn/

第1步:下載TinyMCE
TinyMCE支持多種使用方式,但是本人還是建議使用最傳統的方式,把相關資源下載到本地,放置到項目中。最新版的下載地址https://www.tiny.cloud/get-tiny/ 這裏下載的是默認配置版,就是插件、主題、皮膚都是官方默認指定的。

第2步:引入TinyMCE腳本

<script src="你的網站路徑/tinymce/tinymce.min.js"></script>

第3步:將TinyMCE初始化為頁面的一部分

<!DOCTYPE html>
<html>
<head>
  <script src='tinymce.min.js'></script>
  <script>
  tinymce.init({
    selector: '#mytextarea'
  });
  </script>
</head>

<body>
<h1>TinyMCE快速開始示例</h1>
  <form method="post">
    <textarea id="mytextarea">Hello, World!</textarea>
  </form>
</body>
</html>

第4步:通過正常表單POST保存內容
當form提交時,TinyMCE會將內容塞進textarea,你可以通過正常的post方法獲取到編輯器中的內容,行為與普通textarea完全一致。

2.常見問題處理

問題處理代碼截取自sitesCMS源碼,完整代碼可查閲sitesCMS源碼 https://gitee.com/xhhxb/sitesCMS

2.1.漢化

問題現象
TinyMCE默認是英文的
解決方案
官方提供了語言包,從這個地址下載對應的漢化語言包 https://www.tiny.cloud/get-tiny/language-packages/ 配置語言

language: 'zh-Hans',//漢化語言包

2.2.字體選項沒有中文

問題現象
即便使用了漢化包,但是在選擇字體的下拉菜單中還是沒有中文,這個仍然是配置的問題。
解決方案

font_family_formats: "微軟雅黑=\'微軟雅黑\';宋體=\'宋體\';黑體=\'黑體\';仿宋=\'仿宋\';楷體=\'楷體\';隸書=\'隸書\';幼圓=\'幼圓\';Andale Mono=andale mono,times;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Courier New=courier new,courier;Georgia=georgia,palatino;Webdings=webdings;Wingdings=wingdings",//字體選項

2.3.頁面刷新不顯示

問題原因
sitesCMS中是通過pjax進行頁面局部刷新,刷新時會導致tinymce的init方法得不到執行,導致編輯器不能正常顯示。
解決方案

//先手動銷燬,避免刷新頁面不能正常創建
tinymce.remove('#editor');
//下面再創建
tinymce.init({... ...});

2.4.表單提交沒有值

問題原因
提交表單時沒有及時將編輯器的內容填充到textarea中
解決方案

//ajax提交表單自動同步textarea的問題
editor.on('change',function(){ editor.save(); });

2.5.全屏被遮擋問題

問題原因
sitesCMS後台使用的是layui框架,tinymce全屏時頭部和菜單部分會被遮擋,原因是這兩部分的z-index比較大,位於最上層,導致遮擋下面的內容。
解決方案

//監聽全屏插件的全屏事件,手動處理全屏被遮擋文檔
editor.on('FullscreenStateChanged', function(data){
   if(data.state){
      console.log('全屏');
      $(".layui-header").css("z-index","0");
      $(".layui-side").css("z-index","0");
   } else {
      console.log('取消全屏');
      $(".layui-header").removeAttr("style");
      $(".layui-side").removeAttr("style");
   }
});

2.6.內容被過濾

問題原因
sitesCMS中使用了Jsoup對錶單內容進行過濾,如果配置中沒有把需要保存的標籤放置白名單中會導致部分內容或樣式被過濾而不能保存。
解決方案

/**
 * 放開需要保存的標籤
 */
.addAttributes("video", "src", "controls", "width", "height", "poster", "preload", "muted", "loop", "autoplay")
.addAttributes("source", "src", "type")

2.7.使用表情保存

問題原因
表情字符是4個字節,而mysql中的utf-8最大支持3個字節的存儲,而如果想要存儲4個字節的字符就會報錯,不只是emoji表情,複雜一些的文字也會出現這種情況。
解決方案
調整對應表字段的編碼為utf8bm4即可

2.8.圖片和視頻上傳

圖片和視頻上傳都需要啓用對應的插件,並提供對應的配置和編碼處理,這個代碼和邏輯稍微複雜一點,詳細處理方案參考sitesCMS源碼https://gitee.com/xhhxb/sitesCMS

images_upload_url: '/file/uploadImg4TinyMCE',//圖片上傳地址
file_picker_types: 'media',//只在視頻上傳時提供上傳按鈕
file_picker_callback: function(callback, value, meta) {
    //在視頻上傳彈窗提供一個文件上傳按鈕
    if (meta.filetype == 'media') {
        //callback('movie.mp4', {source2: 'alt.ogg', poster: 'image.jpg'});
        let filetype = '.mp4';
        let url = '/file/uploadVideo4TinyMCE';
        //模擬出一個input用於添加本地文件
        var input = document.createElement('input');
        input.setAttribute('type', 'file');
        input.setAttribute('accept', filetype);
        input.click();

        input.onchange = function () {
            let file = this.files[0];
            let xhr, formData;
            console.log(file.name);
            xhr = new XMLHttpRequest();
            xhr.withCredentials = false;
            xhr.open('POST', url);
            xhr.onload = function () {
                let json;
                if (xhr.status != 200) {
                    layer.msg("文件上傳異常,請檢查文件格式和大小");
                    return;
                }
                json = JSON.parse(xhr.responseText);
                if (!json || typeof json.location != 'string') {
                    layer.msg(json.msg);
                    return;
                }
                callback(json.location);
            };
            formData = new FormData();
            formData.append('file', file, file.name);
            xhr.send(formData);
        }
    }
}