CKEditor 4 CKEDITOR.editor paste事件的深人解析

 

準備一範例,此範例的paste事件是應用於檢查檔案大小。

後端:

public ActionResult UpLoadToDB(HttpPostedFileBase upload)
{
    try
    {
        int img_id = db.IMAGEs.Count() > 0 ? db.IMAGEs.Max(a => a.img_id) + 1 : 1;

        byte[] buffer = new byte[upload.ContentLength];
        upload.InputStream.Read(buffer, 0, upload.ContentLength);

        IMAGE image = new IMAGE();
        image.img_id = img_id;
        image.contentType = upload.ContentType;
        image.imageContent = buffer;

        db.IMAGEs.Add(image);
        db.SaveChanges();

        JObject obj = new JObject(
             new JProperty("uploaded", 1),
             new JProperty("fileName", img_id),
             new JProperty("url", Url.Action("GetImage", new { id = img_id }))
         );

        return Content(JsonConvert.SerializeObject(obj), "application/json");
    }
    catch (Exception ex)
    {
        JObject obj = new JObject(
             new JProperty("uploaded", 0),
             new JProperty("error", new JObject(
                    new JProperty("message", ex.ToString())
                 )
             )
         );

        return Content(JsonConvert.SerializeObject(obj), "application/json");
    }
}

 

前端:

<html>
<head>
    <meta charset="utf-8">
    <title>CKEditor</title>
    <script src="http://cdn.ckeditor.com/4.6.1/standard-all/ckeditor.js"></script>
</head>
<body>
    <textarea name="editor1"></textarea>
    <script>
        var myEditor = CKEDITOR.replace('editor1', {
            extraPlugins: 'uploadimage', //表示使用uploadimage套件
            uploadUrl: '@Url.Action("UpLoadToDB")',

            on: {
                paste: function (evt) {
                    //前端上傳前事先檢查圖檔大小,檔案不得大於800KB
                    if (evt.data.type == "html" && evt.data.dataValue == "") {
                        if (evt.data.dataTransfer.getFile(0).size > 800 * 1024) {
                            alert('The file is too big, please use a smaller one.');
                            evt.stop();
                        }
                    }
                }
            }

        });
    </script>
</body>
</html>

或等於

<html>
<head>
    <meta charset="utf-8">
    <title>CKEditor</title>
    <script src="http://cdn.ckeditor.com/4.6.1/standard-all/ckeditor.js"></script>
</head>
<body>
    <textarea name="editor1"></textarea>
    <script>
        var myEditor = CKEDITOR.replace('editor1', {
            extraPlugins: 'uploadimage', //表示使用uploadimage套件
            uploadUrl: '@Url.Action("UpLoadToDB")'
        });

        myEditor.on('paste', function (evt) {
            //前端上傳前事先檢查圖檔大小,檔案不得大於800KB
            if (evt.data.type == "html" && evt.data.dataValue == "") {
                if (evt.data.dataTransfer.getFile(0).size > 800 * 1024) {
                    alert('The file is too big, please use a smaller one.');
                    evt.stop();
                }
            }
        });
    </script>
</body>
</html>

 

後端只是參考,不是本文章要談的範圍,

先來看型別為CKEDITOR.eventInfo的名稱 evt 物件其內容是什麼

由此可發現 evt 物件確實如 spec 上所寫的一樣,有五個屬性、三個方法。

比較重要的屬性有 data 與 editor 屬性,editor 屬性的型別是CKEDITOR.editor

如果要動到 editor 屬性時,表示將對ckeditor有更深層的應用,

此範例還不用動到 editor 屬性(殺雞焉用牛刀~~~),使用 data 屬性就足夠應付。

 

來看 evt.data 屬性,此範例是將一圖檔拖放到編輯器裡,

所以 evt.data.method 屬性顯示剛發生了「drop」事件,

當放進編輯器裡的是文字時,則 evt.data.type 屬性通常為 text;

而當放進編輯器裡的是圖片時,則 evt.data.type 屬性通常為 html,但請注意這不是絕對。

當放進編輯器裡的是文字時,則 evt.data.dataVaue 屬性為 html string 內容;

而當放進編輯器裡的是圖片時,則 evt.data.dataValue 屬性為空字串。

 

接下來看 CKEDITOR.plugins.clipboard.dataTransfer 型別的 evt.data.dataTransfer 屬性,

由 spec 可知 evt.data.dataTransfer 屬性裡有提供「$」屬性可用來操作DOM object,

看裡面的屬性內容就知道其可應用的地方可多了。

 evt.data.dataTransfer 屬性裡有提供「id」屬性方便於識別該物件,

另外還有提供八種方法供開發者應用

也應該知道範例的 evt.data.dataTransfer.getFile(0) 方法是如何用來判斷圖檔大小了吧。

提醒一點 evt.data.dataTransfer.getFile(0).size 的單位是以byte計算。

 

額外一提,drop、paste、fileUploadRequest事件同時被註冊到編輯器的實體上,

其觸發優先順序為何?答案為drop -> paste -> fileUploadRequest,

了解其觸發優先順序與各個可事件可操作的物件,對以後開發上也是很有幫助的。

<html>
<head>
    <meta charset="utf-8">
    <title>CKEditor</title>
    <script src="http://cdn.ckeditor.com/4.6.1/standard-all/ckeditor.js"></script>
</head>
<body>
    <textarea name="editor1"></textarea>
    <script>
        var myEditor = CKEDITOR.replace('editor1', {
            extraPlugins: 'uploadimage', //表示使用uploadimage套件
            uploadUrl: '@Url.Action("UpLoadToDB")'
        });

        myEditor.on('drop', function (evt) {
            console.log("drop");
        });

        myEditor.on('paste', function (evt) {
            console.log("paste");
        });

        myEditor.on('fileUploadRequest', function (evt) {
            console.log("fileUploadRequest");
        });
    </script>
</body>
</html>

 

editor.on( 'fileUploadRequest', function( evt ) {
    var fileLoader = evt.data.fileLoader,
        formData = new FormData(),
        xhr = fileLoader.xhr;

    xhr.open( 'POST', fileLoader.uploadUrl, true );
    formData.append( 'upload', fileLoader.file, fileLoader.fileName );
    fileLoader.xhr.send( formData );

    // Prevented the default behavior.
    evt.stop();
}, null, null, 4 ); // Listener with a priority 4 will be executed before priority 5.

 

參考資料:

CKEDITOR.editor paste

CKEDITOR.editor drop

CKEDITOR.eventInfo

CKEDITOR.plugins.clipboard.dataTransfer

延伸參考

CKEDITOR.editor fileUploadRequest

CKEDITOR.editor fileUploadResponse

CKEDITOR.fileTools.fileLoader

相關文章

Uploading Dropped or Pasted Files

Clipboard Integration