Jodit富文本編輯器的基本使用(圖片上傳)

Jodit是國外一款開源的WYSIWYG(What You See Is What You Get, 所見即所得)富文本編輯器,用純TypeScript寫成,功能齊全,風格簡約,支持定製。
這是官網地址:https://xdsoft.net/jodit/
本文使用的版本爲Jodit-3.5.1,後端接口用php編寫javascript

使用

下載源碼包,解壓php

<link rel="stylesheet" href="build/jodit.css">
<script src="build/jodit.js"></script>

<div id="editor"></div>
<script>
var editor = new Jodit('#editor');
editor.value = '<p>start</p>';
</script>

大部分設置能夠在官網的Playground頁面下進行交互式定製
經過editor.value能夠獲取或設置編輯器的內容css

圖片上傳

typescript源文件中的默認設置html

Config.prototype.uploader = {
	url: '',
        //在html中插入base64編碼後的圖片,這樣會致使html文本大小過大,且可讀性下降,通常不用,而是選擇設置url將圖片上傳到服務器上,再在html中插入相應的<img>圖片
	insertImageAsBase64URI: false,
        //這裏的圖片類型好像並無什麼用,既不會過濾也不會彈錯誤框
	imagesExtensions: ['jpg', 'png', 'jpeg', 'gif'],
        //添加請求頭
	headers: null,
        //不清楚幹啥的,好像沒什麼用
	data: null,
        //上傳文件的參數名
	filesVariableName(i: number): string {
		return `files[${i}]`;
	},
        //不清楚,查了下是 跨域請求是否提供憑據信息(cookie、HTTP認證及客戶端SSL證實等)
	withCredentials: false,
        //不清楚幹啥的,好像沒什麼用,請求體會有個這個參數,不過是空的
	pathVariableName: 'path',
	format: 'json',
	method: 'POST',
        //添加請求體參數
	prepareData(this: Uploader, formData: FormData) {
		return formData;
	},
        //判斷是否上傳成功
	isSuccess(this: Uploader, resp: IUploaderAnswer): boolean {
		return resp.success;
	},
        //獲取返回值信息
	getMessage(this: Uploader, resp: IUploaderAnswer) {
		return resp.data.messages !== undefined && isArray(resp.data.messages)
			? resp.data.messages.join(' ')
			: '';
	},
        //處理返回值
	process(this: Uploader, resp: IUploaderAnswer): IUploaderData {
		return resp.data;
	},
        //彈出錯誤消息窗
	error(this: Uploader, e: Error) {
		this.j.e.fire('errorMessage', e.message, 'error', 4000);
	},
        //上傳成功時將相應的<img>圖片插入html中
	defaultHandlerSuccess(this: Uploader, resp: IUploaderData) {
		const j = this.j || this;

		if (!isJoditObject(j)) {
			return;
		}

		if (resp.files && resp.files.length) {
			resp.files.forEach((filename, index: number) => {
				const [tagName, attr]: string[] =
					resp.isImages && resp.isImages[index]
						? ['img', 'src']
						: ['a', 'href'];

				const elm = j.createInside.element(tagName);

				elm.setAttribute(attr, resp.baseurl + filename);

				if (tagName === 'a') {
					elm.textContent = resp.baseurl + filename;
				}

				if (tagName === 'img') {
					j.s.insertImage(
						elm as HTMLImageElement,
						null,
						j.o.imageDefaultWidth
					);
				} else {
					j.s.insertNode(elm);
				}
			});
		}
	},
        //彈出錯誤消息窗
	defaultHandlerError(this: Uploader, e: Error) {
		this.j.e.fire('errorMessage', e.message);
	},
        //設置請求頭中的Content-Type
	contentType(this: Uploader, requestData: any) {
		return (this.j.ow as any).FormData !== undefined &&
			typeof requestData !== 'string'
			? false
			: 'application/x-www-form-urlencoded; charset=UTF-8';
	}
} as IUploaderOptions<Uploader>;

以上幾個方法的調用鏈大概是這樣的:
先是prepareData預處理,而後將請求發送給url接口,接口返回json數據,這時先isSuccess判斷是否上傳成功;
若是上傳成功了,調用process處理返回值,接着defaultHandlerSuccess用處理完的返回值向html文本中插入圖片;
若是上傳失敗了,error調用getMessage獲取返回值中的錯誤信息,而後彈出錯誤消息窗。java

下面開始自定義設置
這裏先放一下個人接口的返回值,方便理解代碼
上傳成功的:typescript

{
    "error": false,
    "msgs": [],
    "imgs": [
        {
            "url": "Penguins.jpg",
            "width": 200,
            "height": 150
        },
        {
            "url": "Desert.jpg",
            "width": 200,
            "height": 150
        }
    ]
}

上傳失敗的:json

{
    "error": true,
    "msgs": [
        "test.pdf: 文件類型不支持",
        "test.txt.plain: 文件類型不支持"
    ],
    "imgs": []
}

而後是uploader的設置:後端

uploader: {
    url: 'http://localhost/jodit/upload.php',
    //添加請求頭,使用方法:
    //headers: {"key": "value"}
    headers: null,
    data: null,
    //上傳文件的參數名,該方法參數爲整數(上傳的第幾個文件),以支持多份文件的上傳,返回值爲string
    filesVariableName: function(i){
        return "imgs["+i+"]"
    },
    withCredentials: false,
    pathVariableName: "path",
    format: "json",
    method: "POST",
    //添加請求體參數,該方法參數爲FormData
    prepareData: function(formData){
        //能夠在控制檯打印出來,能看到支持的方法append, delete...
        //console.log(formData);
        formData.append('id', 1)
    },
    //判斷是否上傳成功,該方法參數爲url接口的返回值,返回值爲bool
    isSuccess: function (resp) {
        return !resp.error;
    },
    //獲取返回值信息,該方法參數爲url接口的返回值,返回值爲string
    getMessage: function (resp) {
        return resp.msgs.join('\n');
    },
    //處理返回值,該方法參數爲url接口的返回值,返回值爲json
    //也能夠不處理直接返回,或者過濾一下:return {error: resp.error, msgs: resp.msgs, imgs: resp.imgs}
    process: function (resp) {
        return resp;
    },
    //上傳成功時將相應的<img>圖片插入html中,該方法參數爲process的返回值
    defaultHandlerSuccess: function (resp) {
        for(var i=0; i<resp.imgs.length; i++) {
            //insertImage(url: string | HTMLImageElement, styles: [object Object], defaultWidth: [object Object]): void
            this.s.insertImage(resp.imgs[i]['url'], {width: resp.imgs[i]['width'], height: resp.imgs[i]['height']});
        }
    }
}

最後貼一下完整代碼

jodit.html跨域

<!DOCTYPE html>
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="./jodit-3.5.1/build/jodit.css">
    <script src="./jodit-3.5.1/build/jodit.js"></script>
    <title>Jodit</title>
</head>
<body>
<div id="editor"></div>
<script>
    var editor = new Jodit('#editor', {
        language: 'zh_cn',
        //設置錯誤消息彈窗的顯示時間(ms)
        showMessageErrorTime: 6000,
        uploader: {
            url: 'http://localhost/jodit/upload.php',
            headers: null,
            data: null,
            filesVariableName: function(i){
                return "imgs["+i+"]"
            },
            withCredentials: false,
            pathVariableName: "path",
            format: "json",
            method: "POST",
            prepareData: function(formData){
                formData.append('id', 1)
            },
            isSuccess: function (resp) {
                return !resp.error;
            },
            getMessage: function (resp) {
                return resp.msgs.join('\n');
            }
            process: function (resp) {
                return resp;
            },
            defaultHandlerSuccess: function (resp) {
                for(var i=0; i<resp.imgs.length; i++) {
                    this.s.insertImage(resp.imgs[i]['url'], {width: resp.imgs[i]['width'], height: resp.imgs[i]['height']});
                }
            }
        }
    });
</script>
</body>
</html>

upload.php服務器

<?php
$ALLOW_TYPE = [
    'image/jpg',
    'image/jpeg',
    'image/pjpeg',
    'image/png',
    'image/gif'
];
$ALLOW_SIZE = 3 * 1024 * 1024;
$error = false;
$msgs = array();
$imgs = array();
foreach($_FILES['imgs']['name'] as $i=>$img){
    if($_FILES['imgs']['error'][$i] > 0){
        $error = true;
        $msgs[] = $img.': '.$_FILES['imgs']['error'][$i];
        continue;
    }
    if(!in_array($_FILES['imgs']['type'][$i], $ALLOW_TYPE)){
        $error = true;
        $msgs[] = $img.": 文件類型不支持";
        continue;
    }
    if($_FILES['imgs']['size'][$i] > $ALLOW_SIZE){
        $error = true;
        $msgs[] = $img.": 圖片大小超過3M";
        continue;
    }
}
if(!$error){
    foreach($_FILES['imgs']['name'] as $i=>$img){
        move_uploaded_file($_FILES['imgs']['tmp_name'][$i], $img);
        $imgs[] = [
            'url' => $img,
            'width' => 200,
            'height' => 150
        ];
    }
}
die(json_encode([
    'error' => $error,
    'msgs' => array_reverse($msgs),
    'imgs' => array_reverse($imgs)
]));

本身作後端的,對js不是很熟,若有錯誤歡迎指正,也歡迎解答文中疑惑

相關文章
相關標籤/搜索