天天看點

基于bootstrap的富文本編輯器summernote,重寫圖檔上傳并添加進度條效果圖前言踩坑代碼

效果圖

基于bootstrap的富文本編輯器summernote,重寫圖檔上傳并添加進度條效果圖前言踩坑代碼
基于bootstrap的富文本編輯器summernote,重寫圖檔上傳并添加進度條效果圖前言踩坑代碼

前言

據我了解,這是一款基于bootstrap的富文本編輯器,比較喜歡的它的樣式風格和圖檔上傳的功能。

問題1:

它預設的圖檔上傳,是把圖檔轉成base64編碼并送出給後端。這顯然不是我們想要的,我們希望圖檔以檔案形式送出給後端儲存,後端傳回其儲存的路徑。

問題2:

圖檔異步上傳時,沒有進度顯示。如果上傳動态圖等較大的圖檔,使用者體驗不是很好。為此,我使用一款基于bootstrap的模态框插件 BootBox.js (https://www.bootboxjs.cn/)來顯示上傳進度條。

踩坑

1、bootstrap,bootbox, summernote相關依賴引入,略...

2、summernote的API可能不同版本之間有差異,這裡隻提供重寫圖檔上傳和顯示上傳進度條的思路,summernote具體API參照官網文檔

3、在伺服器部署環境下測試:

(1)有時候發現圖檔插入位置錯誤,并沒有成功插入到編輯框中,但在本地測試沒發現。原因未知。

(2)為什麼進度條滿了之後,要等一會進度條對話框才消失?

上傳進度,是指前端已經發送出去的位元組數,後端完全接收之後。會把臨時檔案移動到指定目錄,并往資料庫中插入資料。業務層面的操作需要耗時。是以,進度條滿了,代表前端已經把所有位元組發送出去。從完全發送完畢到得到響應的中間有一段時間差。當得到響應後,進度條對話框才隐藏。

(3)為什麼進度條對話框隐藏之後,要等一會圖檔才插入到編輯框中?

summernote中插入圖檔的操作是異步的。是以沒有等到插入圖檔完成,進度條對話框就被關閉了。圖檔被插入到編輯框後,要根據網絡URL來加載圖檔,測試發現是完全加載圖檔後才插入到編輯框中顯示出來。如果伺服器帶寬小(我用的學生伺服器),較大的圖檔加載會比較慢。

代碼

<script>
    
    	$(function() { 
            
            var $summernote = $('#summernote').summernote({
                height: 420,
                focus: true,
                toolbar: [
                    ['style', ['style']],
                    ['font', ['bold', 'italic', 'underline', 'clear']],
                    ['fontname', ['fontname']],
                    ['fontsize', ['fontsize']],
                    ['color', ['color']],
                    ['para', ['ul', 'ol', 'paragraph']],
                    ['height', ['height']],
                    ['table', ['table']],
                    ['insert', ['link', 'picture', 'video']],
                    ['view', ['fullscreen', 'codeview']],
                    ['help', ['help']]
                  ], 
            	// 複寫圖檔上傳方法
                onImageUpload: function (files, editor, $editable) {
                    sendFile(files[0], editor, $editable);
                } 
            });

          	//ajax上傳圖檔
            function sendFile(file, editor, $editable) {
                if (file == null) {
                    // 取消或關閉了檔案選擇對話框
          			return;
          		}
          		console.log(editor);
          		console.log($editable);
          		
          		var val = 0; // 進度。百分比
          		var totalBytes = file.size; // 檔案的總位元組數
          		console.log(totalBytes);
          		
                var formData = new FormData();
                formData.append("file", file);
                
                // 顯示進度對話框
                showProgressDialog();
                
                var uploadAjax = $.ajax({
                    url: "圖檔上傳的接口路徑", 
                    type: 'POST',  
                    data: formData,
                    cache: false,
                    contentType: false,
                    processData: false,
                    xhr: function() {
    			        //擷取原生的xhr對象
    			        var xhr = $.ajaxSettings.xhr();
    			        if (xhr.upload) {
    			            //添加 progress 事件監聽
    						//console.log(xhr.upload);
    						xhr.upload.onprogress = function(e) {
    							// e.loaded 已經加載的位元組數
    							val = (int) (e.loaded / totalBytes * 100); 
    							if (val > 100) {
    								val = 100;
    							}
    							
    							// 更新進度條的進度
    							$('#progressBar').css({
    								width: val.toFixed(2) + '%'
    							});
    							$('#progressBar').html(val.toFixed(2) + '%');
    						};
    						xhr.upload.onabort = function() {
    							// 取消上傳的回調
    						};
    			        }
    			        return xhr;
    			    },
                    // ajax請求成功的回調
                    success: function (data) {
                    	console.log(data);
                    	
                    	if (data['result'] === true) {
                    		//console.log($editable);
                            // 異步将圖檔插入到編輯框中
                    		editor.insertImage($editable,  "__public__/" + data['save_path']);
                    		
                    		//$summernote.summernote('insertImage', data['save_path']);
                    	} else {
                    		alert(data['error']);
                    	}
                    	
                    	// 關閉對話框
  		                bootbox.hideAll();
                    }
                });
                
                function showProgressDialog() {
                	var html = 
	                "<div class='progress'><div id='progressBar' class='progress-bar' role='progressbar' style='min-width: 2em;'>" + (val + '%') + "</div></div>";
                	
              		bootbox.dialog({ 
              		    title: '正在上傳...',
              		    message: html,
              		    size: 'large',
              		    onEscape: false,
              		    backdrop: false,

              		    buttons: {
              		        cancel: {
              		            label: '取消',
              		            className: 'btn btn-outline-danger',
              		            callback: function(){
              		                 // 中斷ajax請求
              		                 if (uploadAjax != null) {
										//console.log(uploadAjax);
										uploadAjax.abort();
									}
              		                // 關閉對話框
              		                bootbox.hideAll();
              		            }
              		        }
              		    }
              		});
              	}
            }
     
    	});

    </script>