editormd 支持拖放上传图片和视频

editormd 支持拖放上传图片和视频

editormd中,有时觉得 点击按钮 => 弹出对话框 => 选择文件这样的上传步骤有些麻烦,要是能支持文件拖放上传,将会是非常不错的用户体验。

实现这个功能,关键点有3个:

    1. 监听并处理editormd编辑区域的拖放(Drag-Drop)事件
    1. 放下文件后,获取到文件,通过Ajax上传至后端
    1. 收到后端返回的视频/图片 url,转换成合适的代码片段,粘贴到编辑器中

这3个部分的功能并不是什么特别新的,拖放事件、Ajax上传文件,以前也处理过了。最后一部分则在前面一篇文章中也讲过了。

1. 监听编辑区的拖放事件

首先我们要找到editormd编辑区域的元素,才能对它进行监听拖放事件。

通过Chrome浏览器调试,发现editormd编辑器的编辑区域是class.CodeMirror-wrap的元素。参考HTML5拖放事件的写法,代码大致如下:

var codeEditor = $(".CodeMirror-wrap")[0];
codeEditor.ondragenter = function(e) {
  e.preventDefault();
  e.stopPropagation();
  console.log("dragenter");
  return false;
};
codeEditor.ondragover = function(e) {
  e.preventDefault();
  e.stopPropagation();
  console.log("dragover");
  return false;
};
codeEditor.ondrop = function(e) {
  e.preventDefault();
  e.stopPropagation();
  console.log("drop");
  var files = e.dataTransfer.files // 这里获取到用户拖放的文件
  console.log(files);
  // 其中 ajaxUpload是Ajax上传文件的函数
  // uploadUrl是后端提供的上传地址, uploadCallback是上传后的回调函数,用于生成代码片段并插入编辑器
  ajaxUpload(uploadUrl, files, uploadCallback);
  return false;
};

把这部分代码放在editormd创建后的onload回调函数中,保证$(".CodeMirror-wrap")[0]可以取到值。

2.Ajax上传图片/视频

Ajax上传图片,相信大家已经写过不少了。忘了没关系,这里有代码可以抄。

ajaxUpload函数代码大致如下:

function ajaxUpload(uploadUrl, files, callback) {
  console.log("my ajax upload begin");
  var formData = new FormData();
  formData.append('file', files[0]);
  // 可以添加其他需要传给后端的参数
  $.ajax({
    url: uploadUrl,
    type: 'POST',
    data: formData,
    processData: false, // must, important
    conentType: false, // must, important
    dataType: 'json',
    success: function(data) {
      console.log("result:", data);
      callback(data);
    },
    complete: function(data) {
    }
  });

  return false;
}

3. 生成代码片段,插入编辑器

这部分代码,可以从上一篇文章中借过来。uploadCallback函数的代码大致如下

function uploadCallback(data) {
  var url = data.data.url; // 依据后端返回的数据格式而定
  var link = url;
  if (!url) return false;

  var alt = "";
  var cm = myEditormd; // myEditormd是用editormd函数创建的编辑器对象,这里假设myEditor是全局变量
  var cursor = cm.getCursor(); // 获取光标位置
  if (url.endsWith(".mp4")) { // 如果是是视频
    var videoHtml = '<video class="video-js" controls preload="auto" width="100%" poster="" data-setup=\'{"aspectRatio":"16:9"}\'>\
<source src="' + url + '" type=\'video/mp4\' >\
<p class="vjs-no-js">\
To view this video please enable JavaScript\
</p>\
</video>';
    videoHtml = "\n" + videoHtml + "\n"; // videoHtml是生成的HTML视频代码片段
    cm.replaceSelection(videoHtml); // 插入到编辑器中
    cm.setCursor(cursor.line, cursor.ch + 2);
    return;
  }
  // 以下是对图片上传结果的处理,引用原image-upload插件的代码
  var altAttr = (alt !== "") ? " \"" + alt + "\"" : "";
  if (link === "" || link === "http://")
  {
    cm.replaceSelection("![" + alt + "](" + url + altAttr + ")");
  }
  else
  {
    cm.replaceSelection("[![" + alt + "](" + url + altAttr + ")](" + link + altAttr + ")");
  }

  if (alt === "") {
    cm.setCursor(cursor.line, cursor.ch + 2);
  }
}

这样,我们的editormd编辑器支持拖放上传图片和视频了!

4. 其它

上传的时候,如果文件比较大,需要等待一段时间,这时,最好在编辑区域加上一个显示“正在上传”的加载框,上传后关闭之,这样,用户知道发生了什么。

项目中用的是Vue,使用了饿了么的了Element-ui组件,可以用它提供的的$loading方法来显示加载框,在调用ajax方法上传文件之前插入如下代码:

var loading = that.$loading({ // that是vue实例
  lock: false,
  text: '上传中...',
  spinner: 'el-icon-loading',
  background: 'rgba(0, 0, 0, 0.3)',
  target: '.CodeMirror-wrap',
});
// 假如下面这行代码是因为Element-ui在编辑区显示的遮罩效果太黑了,而且通过`background`选项调整不过来
$(".el-loading-mask").css({'background-color': 'rgba(0,0,0,0.7)'});

然后在ajaxcomplete'回调中关闭loading

$.ajax({
  ...
  complete: function() {
    loading.close();
  }
});

猜你喜欢

转载自blog.csdn.net/chunyuan314/article/details/81022498