最近做一个考试系统,编辑题目要用到富文本编辑,要求可以添加图片、视频和pdf。此前项目中用的都是wangEditor,使用的时候发现只可以上传本地图片,视频只能添加链接,找了其他插件,也没发现比较好用的。所以就看看了看源码。

一、实现效果

实现效果

原本效果

二、源码

下面是wangEditor实现插入视频的代码

function Video(editor){

this.editor = editor;

this.$elem = $('

this.type = 'panel';

// 当前是否 active 状态

this._active = false;

}

// 原型

Video.prototype = {

constructor: Video,

onClick: function onClick(){

this._createPanel();

},

_createPanel: function _createPanel(){

var _this = this;

// 创建 id

var textValId = getRandom('text-val');

var btnId = getRandom('btn');

// 创建 panel

var panel = new Panel(this, {

width: 350,

// 一个 panel 多个 tab

tabs: [{

// 标题

title: '插入视频',

// 模板

tpl: '

\u63D2\u5165

',

// 事件绑定

events: [{

selector: '#' + btnId,

type: 'click',

fn: function fn(){

var $text = $('#' + textValId);

var val = $text.val().trim();

if (val) _this._insert(val); // 插入视频

// 返回 true,表示该事件执行完之后,panel 要关闭。否则 panel 不会关闭

return true;

}

}]

}] // tabs end

}); // panel end

// 显示 panel

panel.show();

// 记录属性

this.panel = panel;

}

// 插入视频

_insert: function _insert(val){

var editor = this.editor;

editor.cmd.do('insertHTML', val + '

}

};

复制代码

三、实现

看完源码之后发现挺简单, 在创建panel的时候添加一个插入视频的panel,完事再实现一个视频上传、插入编辑器就完事了,参考一下文件上传代码。

1. 添加插入视频panel

修改Video.prototype._createPanel方法

_createPanel: function _createPanel(){

var _this = this;

var editor = this.editor;

var uploadImg = editor.uploadImg;

var config = editor.config;

// 创建 id

// 上传视频id

var upTriggerVideoId = getRandom('up-trigger-video');

var upFileVideoId = getRandom('up-file-video');

// 插入视频id

var textValId = getRandom('text-val');

var btnId = getRandom('btn');

// tabs 的配置

var tabsConfig = [

{

title: '上传视频或pdf',

tpl: '

events: [{

// 触发选择图片

selector: '#' + upTriggerVideoId,

type: 'click',

fn: function fn(){

var $file = $('#' + upFileVideoId);

var fileElem = $file[0];

if (fileElem) {

fileElem.click();

} else {

// 返回 true 可关闭 panel

return true;

}

}

}, {

// 选择图片完毕

selector: '#' + upFileVideoId,

type: 'change',

fn: function fn(){

var $file = $('#' + upFileVideoId);

var fileElem = $file[0];

if (!fileElem) {

// 返回 true 可关闭 panel

return true;

}

// 获取选中的 file 对象列表

var fileList = fileElem.files;

if (fileList.length) {

console.log(fileList);

uploadImg.uploadVideo(fileList);

}

// 返回 true 可关闭 panel

return true;

}

}]

}, // first tab end

{

// 标题

title: '插入视频',

// 模板

tpl: '

\u63D2\u5165

',

// 事件绑定

events: [{

selector: '#' + btnId,

type: 'click',

fn: function fn(){

var $text = $('#' + textValId);

var val = $text.val().trim();

if (val) _this._insert(val); // 插入视频

// 返回 true,表示该事件执行完之后,panel 要关闭。否则 panel 不会关闭

return true;

}

}]

} // second tab end

]; // tabs end

// 判断 tabs 的显示

var tabsConfigResult = [];

if (config.uploadVideoServer) {

// 显示“上传视频”

tabsConfigResult.push(tabsConfig[0]);

}

if (config.showLinkVideo) {

// 显示“网络视频”

tabsConfigResult.push(tabsConfig[1]);

}

// 创建 panel

var panel = new Panel(this, {

width: 350,

// 一个 panel 多个 tab

tabs: tabsConfigResult // tabs end

}); // panel end

// 显示 panel

panel.show();

// 记录属性

this.panel = panel;

}

复制代码

2. 实现文件上传

图片上传在UploadImg中uploadImg方法中实现,参考一下,在UploadImg中添加一个uploadVideo方法。

// 上传视频

UploadImg.prototype.uploadVideo: function uploadVideo(files){

var _this3 = this;

if (!files || !files.length) {

return;

}

// ------------------------------ 获取配置信息 ------------------------------

var editor = this.editor;

var config = editor.config;

var uploadVideoServer = config.uploadVideoServer;

var maxSize = config.uploadVideoMaxSize;

var maxSizeM = maxSize / 1024 / 1024;

var maxLength = config.uploadVideoMaxLength || 10000;

var uploadFileName = config.uploadFileName || '';

var uploadVideoParams = config.uploadVideoParams || {};

var uploadVideoParamsWithUrl = config.uploadVideoParamsWithUrl;

var uploadVideoHeaders = config.uploadVideoHeaders || {};

var hooks = config.uploadVideoHooks || {};

var timeout = config.uploadVideoTimeout || 30 * 60 * 1000; // 30分钟

var withCredentials = config.withCredentials;

if (withCredentials == null) {

withCredentials = false;

}

var customUploadVideo = config.customUploadVideo;

if (!customUploadVideo) {

// 没有 customUploadVideo 的情况下,需要如下两个配置才能继续进行图片上传

if (!uploadVideoServer) {

return;

}

}

// ------------------------------ 验证文件信息 ------------------------------

var resultFiles = [];

var errInfo = [];

arrForEach(files, function (file){

var name = file.name;

var size = file.size;

// chrome 低版本 name === undefined

if (!name || !size) {

return;

}

if (/\.(pdf|rm|rmvb|3gp|avi|mpeg|mpg|mkv|dat|asf|wmv|flv|mov|mp4|ogg|ogm)$/i.test(name) === false) {

// 后缀名不合法,不是视频

errInfo.push('\u3010' + name + '\u3011\u4E0D\u662F\u56FE\u7247');

return;

}

if (maxSize < size) {

// 上传视频过大

errInfo.push('\u3010' + name + '\u3011\u5927\u4E8E ' + maxSizeM + 'M');

return;

}

// 验证通过的加入结果列表

resultFiles.push(file);

});

// 抛出验证信息

if (errInfo.length) {

this._alert('视频验证未通过: \n' + errInfo.join('\n'));

return;

}

if (resultFiles.length > maxLength) {

this._alert('一次最多上传' + maxLength + '个视频');

return;

}

// ------------------------------ 自定义上传 ------------------------------

if (customUploadVideo && typeof customUploadVideo === 'function') {

customUploadVideo(resultFiles, this.insertLinkVideo.bind(this));

// 阻止以下代码执行

return;

}

// 添加图片数据

var formdata = new FormData();

arrForEach(resultFiles, function (file){

var name = uploadFileName || file.name;

formdata.append(name, file);

});

// ------------------------------ 上传图片 ------------------------------

if (uploadVideoServer && typeof uploadVideoServer === 'string') {

// 添加参数

var uploadVideoServerArr = uploadVideoServer.split('#');

uploadVideoServer = uploadVideoServerArr[0];

var uploadVideoServerHash = uploadVideoServerArr[1] || '';

objForEach(uploadVideoParams, function (key, val){

// 因使用者反应,自定义参数不能默认 encode ,由 v3.1.1 版本开始注释掉

// val = encodeURIComponent(val)

// 第一,将参数拼接到 url 中

if (uploadVideoParamsWithUrl) {

if (uploadVideoServer.indexOf('?') > 0) {

uploadVideoServer += '&';

} else {

uploadVideoServer += '?';

}

uploadVideoServer = uploadVideoServer + key + '=' + val;

}

// 第二,将参数添加到 formdata 中

formdata.append(key, val);

});

if (uploadVideoServerHash) {

uploadVideoServer += '#' + uploadVideoServerHash;

}

// 定义 xhr

var xhr = new XMLHttpRequest();

xhr.open('POST', uploadVideoServer);

// 设置超时

xhr.timeout = timeout;

xhr.ontimeout = function (){

// hook - timeout

if (hooks.timeout && typeof hooks.timeout === 'function') {

hooks.timeout(xhr, editor);

}

_this3._alert('上传视频超时');

};

// 监控 progress

if (xhr.upload) {

xhr.upload.onprogress = function (e){

var percent = void 0;

// 进度条

var progressBar = new Progress(editor);

if (e.lengthComputable) {

percent = e.loaded / e.total;

progressBar.show(percent);

}

};

}

// 返回数据

xhr.onreadystatechange = function (){

var result = void 0;

if (xhr.readyState === 4) {

if (xhr.status < 200 || xhr.status >= 300) {

// hook - error

if (hooks.error && typeof hooks.error === 'function') {

hooks.error(xhr, editor);

}

// xhr 返回状态错误

_this3._alert('上传视频发生错误', '\u4E0A\u4F20\u56FE\u7247\u53D1\u751F\u9519\u8BEF\uFF0C\u670D\u52A1\u5668\u8FD4\u56DE\u72B6\u6001\u662F ' + xhr.status);

return;

}

result = xhr.responseText;

if ((typeof result === 'undefined' ? 'undefined' : _typeof(result)) !== 'object') {

try {

result = JSON.parse(result);

} catch (ex) {

// hook - fail

if (hooks.fail && typeof hooks.fail === 'function') {

hooks.fail(xhr, editor, result);

}

_this3._alert('上传视频失败', '上传视频返回结果错误,返回结果是: ' + result);

return;

}

}

if (!hooks.customInsert && result.errno != '0') {

// hook - fail

if (hooks.fail && typeof hooks.fail === 'function') {

hooks.fail(xhr, editor, result);

}

// 数据错误

_this3._alert('上传视频失败', '上传视频返回结果错误,返回结果 errno=' + result.errno);

} else {

if (hooks.customInsert && typeof hooks.customInsert === 'function') {

// 使用者自定义插入方法

hooks.customInsert(_this3.insertLinkVideo.bind(_this3), result, editor);

} else {

// 将图片插入编辑器

var data = result.data || [];

data.forEach(function (link){

_this3.insertLinkVideo(link);

});

}

// hook - success

if (hooks.success && typeof hooks.success === 'function') {

hooks.success(xhr, editor, result);

}

}

}

};

// hook - before

if (hooks.before && typeof hooks.before === 'function') {

var beforeResult = hooks.before(xhr, editor, resultFiles);

if (beforeResult && (typeof beforeResult === 'undefined' ? 'undefined' : _typeof(beforeResult)) === 'object') {

if (beforeResult.prevent) {

// 如果返回的结果是 {prevent: true, msg: 'xxxx'} 则表示用户放弃上传

this._alert(beforeResult.msg);

return;

}

}

}

// 自定义 headers

objForEach(uploadVideoHeaders, function (key, val){

xhr.setRequestHeader(key, val);

});

// 跨域传 cookie

xhr.withCredentials = withCredentials;

// 发送请求

xhr.send(formdata);

}

}

复制代码

3. 插入编辑器

插入视频也写在UploadImg.prototype中

// 根据链接插入视频

insertLinkVideo: function insertLinkVideo(link){

if (!link) return;

var _this2 = this;

var editor = this.editor;

var config = editor.config;

// 校验格式

var linkVideoCheck = config.linkVideoCheck;

var checkResult = void 0;

if (linkVideoCheck && typeof linkVideoCheck === 'function') {

checkResult = linkVideoCheck(link);

if (typeof checkResult === 'string') {

// 校验失败,提示信息

alert(checkResult);

return;

}

}

editor.cmd.do('insertHTML', '');

}

复制代码

4. 添加视频上传的默认参数

在config中添加一些上传视频默认参数, 加不加无所谓,在使用方法中都做了参数判断,为了规范代码,这里添加一下。

// 是否显示添加网络视频的 tab

showLinkVideo: true,

// 插入网络视频的回调

linkVideoCallback: function linkVideoCallback(url){

// console.log(url) // url 即插入视频的地址

},

// 默认上传视频 max size: 512M

uploadVideoMaxSize: 512 * 1024 * 1024,

// 配置一次最多上传几个视频

uploadVideoMaxLength: 5,

// 上传视频的自定义参数

uploadVideoParams: {

// token: 'abcdef12345'

},

// 上传视频的自定义header

uploadVideoHeaders: {

// 'Accept': 'text/x-json'

},

// 自定义上传视频超时时间 30分钟

uploadVideoTimeout: 30 * 60 * 1000,

// 上传视频 hook

uploadVideoHooks: {

// customInsert: function (insertLinkVideo, result, editor) {

// console.log('customInsert')

// // 视频上传并返回结果,自定义插入视频的事件,而不是编辑器自动插入视频

// const data = result.data1 || []

// data.forEach(link => {

// insertLinkVideo(link)

// })

// },

before: function before(xhr, editor, files){

// 视频上传之前触发

// 如果返回的结果是 {prevent: true, msg: 'xxxx'} 则表示用户放弃上传

// return {

// prevent: true,

// msg: '放弃上传'

// }

},

success: function success(xhr, editor, result){

// 视频上传并返回结果,视频插入成功之后触发

},

fail: function fail(xhr, editor, result){

// 视频上传并返回结果,但视频插入错误时触发

},

error: function error(xhr, editor){

// 视频上传出错时触发

},

timeout: function timeout(xhr, editor){

// 视频上传超时时触发

}

}

复制代码

四、使用

初始化编辑器,配置上传视频参数

var editor = new window.wangEditor('#text-editor');

// 图片上传

editor.customConfig.uploadImgServer = 'upload/editUpload'; // 上传接口

editor.customConfig.uploadFileName = 'files'; // 上传文件参数名

editor.customConfig.uploadImgHooks = { // 上传完成处理方法

customInsert: function (insertImg, result){

if (result.ret === 200) {

(result.data || '').split(',').forEach(function (link){

link && insertImg(link);

});

} else {

flavrShowByTime('上传失败', null, 'danger');

}

}

};

// 视频上传

editor.customConfig.uploadVideoServer = 'editUpload'; // 上传接口

editor.customConfig.uploadVideoHooks = { // 上传完成处理方法

customInsert: function (insertVideo, result){

if (result.ret === 200) {

(result.data || '').split(',').forEach(function (link){

link && insertVideo(link);

});

} else {

flavrShowByTime('上传失败', null, 'danger');

}

}

};

editor.create();

复制代码

五、写在最后

本来不想改源码的,想直接在使用的时候重写一些其中的方法Video._createPanel、UploadImg、insertImg等。但是,使用的时候调用实例时,Panel、UploadImg都没有挂载到实例上。所以只能修改源码了。就这样!完了!写文章确实不行!

edui 富文本编辑_富文本编辑器wangEditor添加本地上传视频功能相关推荐

  1. SpringBoot2整合富文本编辑器wangEditor(含文件上传)攻略

    背景 最近要用到一个富文本编辑器,记得遥远的年代,调过Kingeditor.Ueditor...但是那些都很重,,,于是最近经常再留意这件事,直到最近看到一个wangEditor,体验了一下,又轻又好 ...

  2. summernote富文本编辑器的自定义附件上传:不限于图片类型

    summernote富文本编辑器的自定义附件上传 前言 一.自定义上传附件按钮和弹窗 二.结合PHP上传文件进行后端处理 三.用jq模拟点击添加链接方式去处理上传附件 前言 summernote的上传 ...

  3. wangeditor 请求头_wangEditor编辑器添加上传视频功能

    正在帮一个朋友的项目进行一些修改,该项目中使用的是 wangEditor 富文本编辑器. 该编辑器的上传视频有个缺陷,不能手动上传,这是目前的效果图 朋友要求加一个上传视频的功能. 网上的解决方案的文 ...

  4. php 编辑器 插入视频,织梦dedecms默认编辑器实现上传视频功能

    织梦默认的编辑器采用的是ckeditor厂商提供的,只可以上传Flash,今天我们进行二次改进,使之可以上传视频文件如MP4文件进行播放,方法比较简单,无需去更换编辑器,下面就言归正传. 第一步:后台 ...

  5. WangEdit富文本编辑器增加上传视频功能

    乘着今天中午的时间 对以前项目的一个需求进行一定的处理 前天去了甲方公司 接到了了一个新的需求 就是可以把项目的一个富文本的编辑器可以设置为能够上传视频 于是乎 就要对vue里面的这个组件进行操作了 ...

  6. Spring Boot集成Ueditor富文本编辑器,实现图片上传,视频上传,返回内容功能并且通过OSS转换为链接并且解决Spring Security静态资源访问以及跨域问题

    学习自https://cloud.tencent.com/developer/article/1452451 现在是晚上22点,刚刚和我们的前端交流完了富文本编辑器的一些意见和看法 还是老样子 需求 ...

  7. Simditor 富文本编辑器多选图片上传、视频连接插入

    simditor 是一个基于浏览器的所见即所得的文本编辑器.Simditor 富文本编辑器, 支持多选图片上传, 视频连接插入, HTML代码编辑以及常用富文本按钮,支持的浏览器:IE10.Firef ...

  8. laravel-admin引用wangEditor编辑器 使用二:上传视频/音频(2)

    完整的wangEditor.js代码 (function (global, factory) {typeof exports === 'object' && typeof module ...

  9. 【前端】wangeditor源码修改,打包发布到npm,实现上传视频功能,得到视频的第一帧保存为封面,spring-boot+vue,axios实现文件上传,视频图片浏览

    一.实现 1.创建git分支,clone下源码 git地址 创建分支 2.图片上传具有文件选择的功能,所以我完全模仿(抄袭)图片上传 报错不慌,全部改完就不报错了 1)在src/config/inde ...

最新文章

  1. 当遭遇“用户增长”停滞,你应该怎么办?
  2. 用数组实现从文件搜索帐户和验证密码
  3. [POI2002][HAOI2007]反素数
  4. PyInstaller库函数
  5. Tomcat输出catalina.out的大小控制
  6. redis desktop manager_面试官:Redis分布式锁如何解决锁超时问题?
  7. spring boot集成mybatis+事务控制
  8. letsencrypt 免费https安装过程linux centos
  9. linux 复制文件或者文件
  10. Log4--Java日志记录器
  11. layDate1.0正式公布,您一直在寻找的的js日期控件
  12. oracle忘记sys密码处理
  13. 百度云无限速下载工具:JDownloader 2 for Mac
  14. 免费OCR文字识别软件,识别图片文字
  15. 史上最详细的接口测试,一篇学会接口
  16. 汤普森算法_什么是汤普森采样(Thompson sampling)?
  17. 【GameMaker】协程——异步执行代码
  18. 推荐9个适合Python开发的IDE。
  19. Rasa 3.x 学习系列-Rasa [3.4.1] - 2023-01-19新版本发布
  20. BigDecimal的用法之乘除、保留小数

热门文章

  1. 源中瑞区块链溯源系统,溯源行业生态信息化解决方案
  2. YouTubeDNN
  3. 自动装箱和自动拆箱——源码分析
  4. 物联网大数据存储利器IoTDB介绍
  5. (热学 热力学统计物理 )大题典选--------热力学第二定律与熵
  6. POJ2584_T-Shirt Gumbo(二分图多重最大匹配/最大流)
  7. 计算机一级考试操作题基础操作,计算机一级考试基础操作题.doc
  8. VSCode修改配置(设置settings.json)汇总
  9. 杰理之 U盘、T卡顺序切换【篇】
  10. HF-Net初探之一:简介与配置使用