ueditor中遇到的坑

ueditor中遇到的坑

最近进入一个go开发项目组,我一个java开发的第一个任务就是研究ueditor组件的使用,嗨,来来回回花了5天多吧,特意写下这篇文章,记住在ueditor中踩过的坑。
1.不晓得前端下的ueditor是哪个版本,就是和百度上面的主流不一样,搞的我想弄死他。打开ueditor的富文本编辑器,点击图片也好视频也好,就是报上面后台配置错误,最后我在ueditor.config.js中加入的多图片上传和视频上传的配置。

  //为编辑器实例添加一个路径,这个不能被注释
    UEDITOR_HOME_URL: URL,

    // 服务器统一请求接口路径
    serverUrl: gHost + 'ybufweb/uploadfile',

    /* 上传视频配置 */
    videoActionName: gHost + 'ybufweb/uploadfile', /* 执行上传视频的action名称 */
    videoFieldName: "file_data", /* 提交的视频表单名称 */
    videoPathFormat: "root/images/{yyyy}{mm}{dd}/{time}{rand:6}/", /* 上传保存路径,可以自定义保存路径和文件名格式 */
    videoUrlPrefix: "", /* 视频访问路径前缀 */
    videoMaxSize: 100000000, /* 上传大小限制,单位B,默认100MB */
    videoAllowFiles: [".mp4", ".webm", ".mp3", ".wav", ".ogg"], /* 上传视频格式显示 */
        
        
     /* 上传图片配置项 */
     imageActionName: gHost + 'ybufweb/uploadfile', /* 执行上传图片的action名称 */
     imageFieldName: "file_data", /* 提交的图片表单名称 */
     imageMaxSiz: 1000000, /* 上传大小限制,单位B */
     imageAllowFiles: [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 上传图片格式显示 */
     imageCompressEnable: true, /* 是否压缩图片,默认是true */
     imageCompressBorder: 1600, /* 图片压缩最长边限制 */
     imageInsertAlign: "none", /* 插入的图片浮动方式 */
     imageUrlPrefix: "", /* 图片访问路径前缀 */
     imagePathFormat: "root/images/{yyyy}{mm}{dd}/{time}{rand:6}/", /* 上传保存路径,可以自定义保存路径和文件名格式 */
                               

2.ueditor中的多图片上传
找了半天才晓得,多图片上传的页面就在image包中,自己去组件中找一下就可以找到。然后呢,我在image.html中把不需要的标签页全部隐藏掉,就留下本地多图片上传。ueditor中遇到的坑_第1张图片

好吧,这样ueditor组件就会往我指定在ueditor.config.js中的serverUrl属性。结果一看后台,需要传一个自定义的参数,这是早就定义好了的公共方法不能修改,怎么办。百度了一下。在使用组件的article-management-save.js页面中
var ue = UE.getEditor(‘editor’);初始化组件时后,

ue.ready(function () {
	ue.execCommand('serverparam', {
		'filetype': 'upload_file',
	});
	ue.queryCommandValue('serverparam');
});

意思就是名字为filetype=‘upload_file’的参数通过get传到后台。结果我后台是post接收的。查看方法,确实是有get传递filetype参数,那么在后台怎么获得呢

if poststr == "" {
		strs := r.Form["filetype"]
		if len(strs) > 0 {
			poststr = strs[0]
		}
	}
意思就是在post中找不到filetype的值,我就去找get的。

然后呢,就是后台返回的json。妈卖批,后台因为是公共的方法,改不了,怎么办呢。改源代码吧。垃圾ueditor。

 uploader.on('uploadSuccess', function (file, ret) {
                var $file = $('#' + file.id);
                try {
                    var responseText = (ret._raw || ret),
                        json = utils.str2json(responseText);
                    //这里是上传之后的回执事件,进行json加工处理
                    json = changeDataToJson(json);
                    if (json.state == 'SUCCESS') {
                        //   _this.imageList.push(json);
                        _this.imageList[$file.index()] = json;
                        $file.append('');
                    } else {
                        $file.find('.error').text(json.state).show();
                    }

                } catch (e) {
                    $file.find('.error').text(lang.errorServerUpload).show();
                }
            });

image.js在uploader.on(‘uploadSuccess’, function (file, ret) {方法中就是对于后台返回json的处理。不符合ueditor的格式。那么我就把他转为符合的格式呗。
ueditor中遇到的坑_第2张图片

在下面我定义了方法changeDataToJson()

	 /** 自己写的方法,把返回的json拼成需要的格式 **/
    function changeDataToJson(json) {
        var object = {
            "original": '', "size": '',
            "state": '', "title": '', "type": '',
            "msg": '', "url": ''
        };

        var _json = json;
        if (_json.msg == 'OK') {
            object.state = 'SUCCESS';
        } else {
            object.state = 'ERROR';
        }
        object.url = _json.results;

        return object;
    }

下面就是重点了。在ueditor中找了半天,就是没有找到多图片上传的张数的限制。这个是什么鬼情况。产品说限制50张,不干到时候又给提bug。

首先在article-management-save.页面的js中定义了

var fileCount= 0;//计算该页面中img标签的个数


//监听ueditor中内容改变事件
ue.addListener("contentChange",function(){
	fileCount=$(ue.getContent()).find("img").length;
   // console.log('内容改变:'+ue.getContent());

   //动态修改视频、音频上传的参数
  recompose();
});

这样我监听ueditor的文本改变事件,去计算已经有了多少个图片。然后在image.js中通过top.window.document.getElementById(“layui-layer-iframe1”).contentWindow.fileCount获取到article-management-save.js中得到的img图片个数,再加上在image.js上面定义的fileCount(这次上传的图片个数),俩着相加就是图片总数了。

 $upload.on('click', function () {
                //获取父级页面得到的图片总数,fileCount为该次上传的图片数量
                var sum = top.window.document.getElementById("layui-layer-iframe1").contentWindow.fileCount + fileCount;
                console.log(sum);
                if (sum > 50) {
                    msgalter("图片总数为" + sum + "张,超过50张,限制上传!");
                    return;
                }

                if ($(this).hasClass('disabled')) {
                    return false;
                }

                if (state === 'ready') {
                    uploader.upload();
                } else if (state === 'paused') {
                    uploader.upload();
                } else if (state === 'uploading') {
                    uploader.stop();
                }
            });

$upload.on(‘click’, function () {方法就是你点击开始上传时按钮触发的世界。

本来以为这样就行了,结果发现表情也是图片,我擦,还需要统计表情的总数,在emotion文件夹的emotion.js中找到function InsertSmiley( url, evt ) {方法
如果,超过50个就不能点击

	function InsertSmiley( url, evt ) {
    //console.log("...C..");
    var sum = top.window.document.getElementById("layui-layer-iframe1").contentWindow.fileCount;
    if(sum >= 50){
        msgalter("图片总数为" + sum + "张,超过50张,限制上传!");
        return;
    }
    
    var obj = {
        src:editor.options.emotionLocalization ? editor.options.UEDITOR_HOME_URL + "dialogs/emotion/" + url : url
    };
    obj._src = obj.src;
    editor.execCommand( 'insertimage', obj );
    if ( !evt.ctrlKey ) {
        dialog.popup.hide();
    }
}

顺便说一下,怎么把表情的http图片改为https,就是在emotion.js中

	emotion.SmileyPath = editor.options.emotionLocalization === true ? 'images/' : "https://img.baidu.com/hi/";

就是把http改为了HTTPS,然后在emotion.html页面中加入
ueditor中遇到的坑_第3张图片

ok,图片告一段落

3.视频、音频上传
其他的问题,百度应该就可以解决,懒的说。我是视频和音频在一起上传的。所以基本是在video包中。然后呢,上传之后的json回执和图片上传一样的需要处理。

 uploader.on('uploadSuccess', function (file, ret) {
             //   console.log(file, ret);
                var $file = $('#' + file.id);
                try {
                    var responseText = (ret._raw || ret),
                        json = utils.str2json(responseText);
                        //这里是上传之后的回执事件,进行json加工处理
                        json = changeDataToJson(json);
             //           console.log(json,"...");
                    if (json.state == 'SUCCESS') {
                        uploadVideoList.push({
                            'url': json.url,
                            'type': json.type,
                            'original':json.original
                        });
                        $file.append('');
                    } else {
                        $file.find('.error').text(json.state).show();
                    }
                } catch (e) {
                    $file.find('.error').text(lang.errorServerUpload).show();
                }
            });
                    /** 自己写的方法,把返回的json拼成需要的格式 **/
            function changeDataToJson(json){
                var object = {"original":'',"size":'',
                        "state":'',"title":'',"type":'',
                        "msg":'',"url":''};

                var _json = json;
                if(_json.msg == 'OK'){
                    object.state = 'SUCCESS';
                }else{
                    object.state = 'ERROR';
                }
                object.url = _json.results;
                
                return object;
            }

接下来问题来了,需求就是一个视频一个音频,
第一步就是在视频上传中一次只能上传一个,找了半天在点击上传时控制最好,

 $upload.on('click', function (file) {
                //限制视频、音频上传,一次只能上传一个
                if (fileCount > 1) {
                    msgalter("一次只能上传一个!");
                    return;
                }
       //         console.log("...5...",file);

                //在这里判断在objectAudio中有值(说明是音频),需要重新校验音频的大小为10M
            //    console.log(objectAudio,file)
                if(objectAudio !=undefined && objectAudio != '' && objectAudio !=null){
                 //   console.log(objectAudio.size);
                    //设置音频的大小为10M
                    if(objectAudio.size > 10000000){
                        msgalter("音频超过10M,请重新上传!");
                        return;
                    }
                }

                if ($(this).hasClass('disabled')) {
                    return false;
                }

                if (state === 'ready') {
                    uploader.upload();
                } else if (state === 'paused') {
                    uploader.upload();
                } else if (state === 'uploading') {
                    uploader.stop();
                }
            });

//限制视频、音频上传,一次只能上传一个
if (fileCount > 1) {
msgalter(“一次只能上传一个!”);
return;
}
就可以控制单上传了

第二步 怎么去保证只能上传一个视频一个音频呢
ueditor.config.js页面中我写的
ueditor中遇到的坑_第4张图片
videoAllowFiles: [".mp4", “.webm”, “.mp3”, “.wav”, “.ogg”], /* 上传视频格式显示 */ 中包含了视频音频。所以第一次是可以上传视频或者音频的,假如我现在上传了一个视频,如果我把videoAllowFiles的值改为[".mp3", “.wav”, “.ogg”],那么以后就只能上传音频了,上传完音频后就把videoAllowFiles数组的值清空,什么都不能上传。
首先在article-management-save.js中定义方法

//动态修改视频、音频的参数
function recompose(){
	//监听如果有视频
	var video =$(ue.getContent()).find("video").length;
	var audio = $(ue.getContent()).find("audio").length;
//	console.log('内容改变:'+video+"...."+audio,"..."+window.UEDITOR_CONFIG.videoAllowFiles);
	if(video>0 && audio==0){//监听如果有视频
		//需要去更改ueditor.config.js中videoAllowFiles的值为audioDeploy,只能上传音频,和音频的大小为10M
		window.UEDITOR_CONFIG.videoAllowFiles.splice(0,5);//清除全部的数组内容
		window.UEDITOR_CONFIG.videoAllowFiles.push(".mp3", ".wav", ".ogg");//重新添加
	//	window.UEDITOR_CONFIG.videoMaxSize = 1000000;
	//	console.log( window.UEDITOR_CONFIG.videoAllowFiles);
	 //   ue = UE.getEditor('editor');
	}else if(video == 0 && audio>0){
		 window.UEDITOR_CONFIG.videoAllowFiles.splice(0,5);//清除全部的数组内容
		 window.UEDITOR_CONFIG.videoAllowFiles.push(".mp4", ".webm");//重新添加
	//	 window.UEDITOR_CONFIG.videoMaxSize = 100000000;
 //		console.log( window.UEDITOR_CONFIG.videoAllowFiles);
	 //	ue = UE.getEditor('editor');
	}else if(video > 0 && audio>0){
		 window.UEDITOR_CONFIG.videoAllowFiles.splice(0,5);//清除全部的数组内容
	 //	ue = UE.getEditor('editor');
	}else if(video == 0 && audio == 0){
		 window.UEDITOR_CONFIG.videoAllowFiles.splice(0,5);//清除全部的数组内容
		 window.UEDITOR_CONFIG.videoAllowFiles.push(".mp4", ".webm", ".mp3", ".wav", ".ogg");//重新添加
	}
}

在以前的方法中加入

//监听ueditor中内容改变事件
ue.addListener("contentChange",function(){
	fileCount=$(ue.getContent()).find("img").length;
   // console.log('内容改变:'+ue.getContent());

   //动态修改视频、音频上传的参数
  recompose();
});

为什么这么写,因为数组有一个特别奇怪的地方。如果,数组ABC,在数组A中定义好内容,然后B=A,C=B,那么如果我给数组A重新赋值,A=D,那么请问C=A(老A),还是C=D。哈哈,可以去试一试。
如果
window.UEDITOR_CONFIG.videoAllowFiles=[".mp3", “.wav”, “.ogg”];
虽然输出window.UEDITOR_CONFIG.videoAllowFiles的值确实变化了,但是在ueditor中并不是直接用的videoAllowFiles属性,而是,XXXX=videoAllowFiles,然后YYYY=XXX,天知道转了多少层,所以没有效果。但是我直接操作该数组。
window.UEDITOR_CONFIG.videoAllowFiles.splice(0,5);//清除全部的数组内容
window.UEDITOR_CONFIG.videoAllowFiles.push(".mp3", “.wav”, “.ogg”);//重新添加
这样就没有问题。一定要记得 这一点。

以上实现了一次只能上传一个和保证了视频和音频只有一个的问题。但是问题来了,我视频最大为100M,音频最大为10M。
在video.js中,最后的getQueueCount: function () {方法中

getQueueCount: function () {
            var file, i, status, readyFile = 0, files = this.uploader.getFiles();
            for (i = 0; file = files[i++]; ) {
                status = file.getStatus();
                if (status == 'queued' || status == 'uploading' || status == 'progress') readyFile++;
            }
     //       console.log(file,"...7...",files);
            //在这里判断,files中的第一个值(因为是单上传),ext是".mp3", ".wav", ".ogg",说明是音频
            //把值给到定义的变量objectAudio中,再到823方法中去判断就可以限制音频的上传大小了
            var fileAudio = files[0];
            objectAudioList = files;
            if(files.length>0){//循环集合,如果值为ext是".mp3", ".wav", ".ogg",说明是音频
                if(fileAudio.ext == 'mp3' || fileAudio.ext == 'wav' || fileAudio.ext == 'z'){
                    objectAudio = fileAudio;
                }
            }
            
            return readyFile;
        },

当然了在最上面定义俩参数

var objectAudio;//用来存储音频file对象
var objectAudioList;//用来存储file数组

因为是单上传,所以我在这里获取到files数组,取到第一个,再去判断如果是音频,就给objectAudio值。最后在$upload.on(‘click’, function (file) {中ueditor中遇到的坑_第5张图片
这样就可以判断是音频时,点击上传按钮时进行重新校验。但是,如果那个手欠的一次选择多个,然后因为提示是只能单上传,一个个删除时,没有进去getQueueCount: function () {方法了,这个时候进去的是删除方法uploader.on(‘fileDequeued’, function (file) {

 uploader.on('fileDequeued', function (file) {
                fileCount--;
                fileSize -= file.size;
              //  console.log(file,fileSize,files);
                removeFile(file);
         
                //删除在objectAudioList数组中的file对象
            //    console.log($.inArray(file,objectAudioList));
                objectAudioList.splice($.inArray(file,objectAudioList),1);
                if(objectAudioList.length>0){
                    //反正取第一个(单视频、音频上传)
                    if(objectAudioList[0].ext == 'mp3' || objectAudioList[0].ext == 'wav' || objectAudioList[0].ext == 'z'){
                        objectAudio = objectAudioList[0];
                    }
                }else{//如果没有长度了,就把objectAudio为空,其实加不加无所谓,反正不会上传
                    objectAudio = null;
                }
                
             //   console.log("...1...",file,objectAudioList);

                updateTotalProgress();
              //  getQueueCount();
               
            });

稍微解释一下。objectAudioList的值在getQueueCount: function () {中定义了
ueditor中遇到的坑_第6张图片
通过

$.inArray(file,objectAudioList)

可以获得,要删除的file在数组中的下标,然后根据下标删除掉该元素咯

objectAudioList.splice($.inArray(file,objectAudioList),1);

接下来,富文本中对于字数的限制只有提示,超过了之后还是可以输入,这样明显不合适,解决思路如下:
找到ueditor中遇到的坑_第7张图片代码如下:

 if (count > max) {//解决超过字数,只提示,还可以输入的问题
          // countDom.innerHTML = errMsg;
          // editor.fireEvent("wordcountoverflow");
          msgalter('文章内容限5000字以内');
          var content = editor.getContentTxt();
          editor.setContent(content.substring(0,max));
          editor.focus(true);
        }

下一个bug 在有的人电脑上谷歌浏览器居然会出现ueditor无法滚动到底部工具栏浮动bug,解决方法

再这里是创建刚才div 的js ,这里加上编辑器的高就可以,量了一下大概79px,jia将上面代码替换为
placeHolder.style.height = toolbarBox.offsetHeight+120.75+ 'px';

这样 又解决了一个bug,基本上 视频音频上传就没有什么问题了。

你可能感兴趣的:(前端)