js拖拽粘贴上传与CodeMirror

Markdown编辑器选用https://simplemde.com
它是一款纯js完成的markdown编辑器。瑕玷不支撑图片上传。那我们就得革新它。
simplemde是基于codemirror编辑器的.
先引见基础:
codemirror文档:http://codemirror.net/doc/man…
simplemde文档:https://github.com/NextStepWe…
API文档:
拖拽:
https://developer.mozilla.org…
https://developer.mozilla.org…

粘贴:
https://developer.mozilla.org…
https://developer.mozilla.org…

注重一点:现在firefox与chrome比较新的版本都完成了这些API。

paste事宜

绑定的元素不一定是input,平常的div也是能够绑定的,假如是给document绑定了,就相当于全局了,任何时刻的粘贴操纵都邑触发。
猎取事宜对象ClipboardEvent
先写一下事宜绑定的代码

pasteEle.addEventListener("paste", function (e){
    if ( !(e.clipboardData && e.clipboardData.items) ) {
        return ;
    }
 
    for (var i = 0, len = e.clipboardData.items.length; i < len; i++) {
        var item = e.clipboardData.items[i];
 
        if (item.kind === "string") {
            item.getAsString(function (str) {
                // str 是猎取到的字符串
            })
        } else if (item.kind === "file") {
            var pasteFile = item.getAsFile();
            // pasteFile就是猎取到的文件
        }
    }
});

粘贴事宜供应了一个clipboardData的属性,假如该属性有items属性,那末就能够检察items中是不是有图片范例的数据了。
clipboardData引见
引见一下clipboardData对象,它实际上是一个DataTransfer范例的对象,DataTransfer 是拖动发生的一个对象,但实际上粘贴事宜也是它。
属性引见
dropEffect String 默许是 none
effectAllowed String 默许是 uninitialized
files FileList 在粘贴操纵时为空List
items DataTransferItemList 剪切板中的各项数据
types Array 剪切板中的数据范例。

DataTransferItem
items是一个DataTransferItemList对象,天然内里都是DataTransferItem范例的数据了。
DataTransferItem有两个属性kind和type

kind 平常为string或许file
type 详细的数据范例,比方详细是哪一种范例字符串或许哪一种范例的文件,即MIME-Type,罕见的值有text/plain、text/html、Files。
要领

getAsFile 空 假如kind是file,能够用该要领猎取到文件
getAsString 回调函数 假如kind是string,能够用该要领猎取到字符串,字符串须要用回调函数取得,回调函数的第一个参数就是剪切板中的字符串
综合

// demo 顺序将粘贴事宜绑定到 document 上
document.addEventListener("paste", function (e) {
    var cbd = e.clipboardData;
    //var ua = window.navigator.userAgent;
 
    for(var i = 0; i < cbd.items.length; i++) {
        var item = cbd.items[i];
        if(item.kind == "file"){
            var blob = item.getAsFile();
            if (blob.size === 0) {
                return;
            }
            // blob 就是从剪切板取得的文件 能够举行上传或其他操纵
        }
    }
}, false);

drop事宜

DragEvent
DragEvent.dataTransfer

dropEffect String 默许是 none
effectAllowed String 默许是 uninitialized
files FileList
items DataTransferItemList 剪切板中的各项数据
types Array 剪切板中的数据范例。
DataTransferItem
items是一个DataTransferItemList对象,天然内里都是DataTransferItem范例的数据了。

DataTransferItem有两个属性kind和type

kind 平常为string或许file
type 详细的数据范例,比方详细是哪一种范例字符串或许哪一种范例的文件,即MIME-Type,罕见的值有images/*、text/plain、text/html、Files。
要领

getAsFile 空 假如kind是file,能够用该要领猎取到文件
getAsString 回调函数 假如kind是string,能够用该要领猎取到字符串,字符串须要用回调函数取得,回调函数的第一个参数就是剪切板中的字符串

dropEle.addEventListener("drop", function (e){
    var data = new FormData();
    var files = event.dataTransfer.files;
    var i = 0;
    var len = files.length;
    while (i < len){
        data.append("file" + i, files[i]);
         i++;
    }
    var xhr = new XMLHttpRequest();
    xhr.open("post", "/upload", true);
    xhr.onreadystatechange = function(){
         if (xhr.readyState == 4){
             alert(xhr.responseText);
         }
     };
     xhr.send(data);
});

阻挠浏览器默许翻开拖拽文件的行动:参考这里

window.addEventListener("drop",function(e){
  e = e || event;
  console.log(e);
  //e.preventDefault();
  if (e.target.tagName != "textarea") {  // check wich element is our target
    e.preventDefault();
  }  
},false);

理论知识说完了。下面最先试验革新codemirror

codemirror支撑粘贴和拖拽上传

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>codemirror</title>
    <link rel="stylesheet" href="codemirror.css">
    <script src="codemirror.js"></script>
</head>
<body>
    <textarea name="aaa" id="aaa"></textarea>
    <script>
    var textarea=document.getElementById("aaa")
      var editor = CodeMirror.fromTextArea(textarea, {
        lineNumbers: true
      });
  editor.on("paste",function(editor,e){
      // console.log(e.clipboardData)
      if(!(e.clipboardData&&e.clipboardData.items)){
          alert("该浏览器不支撑操纵");
          return;
      }
      for (var i = 0, len = e.clipboardData.items.length; i < len; i++) {
        var item = e.clipboardData.items[i];
       // console.log(item.kind+":"+item.type);
        if (item.kind === "string") {
            item.getAsString(function (str) {
                // str 是猎取到的字符串
            })
        } else if (item.kind === "file") {
            var pasteFile = item.getAsFile();
            // pasteFile就是猎取到的文件
            console.log(pasteFile);
            fileUpload(pasteFile);
        }
    }
  });
  editor.on("drop",function(editor,e){
      // console.log(e.dataTransfer.files[0]);
      if(!(e.dataTransfer&&e.dataTransfer.files)){
          alert("该浏览器不支撑操纵");
          return;
      }
      for(var i=0;i<e.dataTransfer.files.length;i++){
          console.log(e.dataTransfer.files[i]);
          fileUpload(e.dataTransfer.files[i]);
      }
      e.preventDefault();
  });
  //文件上传
  function fileUpload(fileObj){
      var data = new FormData();
      data.append("file",fileObj);
      var xhr = new XMLHttpRequest();
    xhr.open("post", "/upload", true);
    xhr.onreadystatechange = function(){
         if (xhr.readyState == 4){
             alert(xhr.responseText);
         }
     };
     xhr.send(data);
  }
  //阻挠浏览器默许翻开拖拽文件的行动
  window.addEventListener("drop",function(e){
  e = e || event;
  e.preventDefault();
  if (e.target.tagName == "textarea") {  // check wich element is our target
    e.preventDefault();
  } 
},false);
</script>
</html>

附Codemirror经常运用事宜与要领
参考这里
1.onChange(instance,changeObj):codeMirror文本被修正后触发。
instance是一个当前的codemirror对象,changeObj是一个{from,to,text,removed}对象。个中from,to离别示意肇端行对象和完毕行对象,行对象包括ch:转变位置距离行头的距离字符,line:转变的行数。text是一个字符串数组示意被修正的文本内容,即你输入的内容。

2.onBeforeChange(instance,changObj):内容转变前被挪用
3.onCursorActivity(instance):当鼠标点击内容区、选中内容、修正内容时被触发
4.onKeyHandled:(instance,name,event):当一个都dom元素的事宜触发时挪用,name为操纵称号。
5.onInputRead(insatance,changeObj):当一个新的input从隐蔽的textara读掏出时挪用
6.onBeforeSelectionChange(instance,obj):当选中的地区被转变时挪用,obj对象是挑选的局限和转变的内容(本人未测试胜利)
7.onUpdate(instance):编辑器内容被转变时触发
8.onFocus(instance):编辑器取得核心式触发
9.onBlur(instance):编辑器落空核心时触发

经常运用要领:
getValue():猎取编辑器文本内容
setValue(text):设置编辑器文本内容
getRange({line,ch},{line,ch}):猎取指定局限内的文本内容第一个对象是肇端坐标,第二个是完毕坐标
replaceRange(replaceStr,{line,ch},{line,ch}):替代指定地区的内容
getLine(line):猎取指定行的文本内容
lineCount():统计编辑器内容行数
firstLine():猎取第一行行数,默许为0,从最先计数
lastLine():猎取末了一行行数
getLineHandle(line):依据行号猎取行句柄
getSelection():猎取鼠标选中地区的代码
replaceSelection(str):替代选中地区的代码
setSelection({line:num,ch:num1},{line:num2,ch:num3}):设置一个地区被选中
somethingSelected():推断是不是被挑选
getEditor():猎取CodeMirror对像
undo():打消
redo():回退

simplemde支撑粘贴和拖拽上传

var simplemde = new SimpleMDE({ element: document.getElementById("MyID") });
simplemde.codemirror.on("drop", function(editor,e){
    ...
});
simplemde.codemirror.on("paste",function(editor,e){
...
});

Blob对象转File对象

为了运用WebUploader这个文件上传组件,须要将粘贴取得的Blob对象转为File对象。
Blob 对象是包括有只读原始数据的类文件对象.File 接口基于 Blob,继续了 Blob 的功用,而且扩大支撑用户盘算机上的当地文件。

var blob=new Blob();
var file = new File([blob], "image.png", {type:"image/png"});

File组织器的第一个参数必需是数组

WebUploader文件上传

http://fex.baidu.com/webuploa…
建立Uploader对象

var uploader = WebUploader.Uploader({
    swf: 'path_of_swf/Uploader.swf',
 
    // 开起分片上传。
    chunked: true
});

监听fileQueued事宜来完成进度UI组织:

// 当有文件被增加进行列的时刻
uploader.on( 'fileQueued', function( file ) {
    var $list=$("#list");
    $list.append( '<div id="' + file.id + '" class="item">' +
        '<h4 class="info">' + file.name + '</h4>' +
        '<p class="state">守候上传...</p>' +
    '</div>' );
});

文件上传进度:

// 文件上传过程当中建立进度条及时显现。
uploader.on( 'uploadProgress', function( file, percentage ) {
    var $li = $( '#'+file.id ),
    $percent = $li.find('.progress .progress-bar');
    // 防止反复建立
    if ( !$percent.length ) {
        $percent = $('<div class="progress progress-striped active">' +
          '<div class="progress-bar" role="progressbar" style="width: 0%">' +
          '</div>' +
        '</div>').appendTo( $li ).find('.progress-bar');
    }
 
    $li.find('p.state').text('上传中');
    $percent.css( 'width', percentage * 100 + '%' );
});

文件胜利、失利处置惩罚:

uploader.on( 'uploadSuccess', function( file,data ) {
    $( '#'+file.id ).find('p.state').text('已上传');
});
 
uploader.on( 'uploadError', function( file ) {
    $( '#'+file.id ).find('p.state').text('上传失足');
});
 
uploader.on( 'uploadComplete', function( file ) {
    $( '#'+file.id ).find('.progress').fadeOut();
});

增加文件到行列并上传:

uploader.addFiles( file ) 
uploader.addFiles( [file1, file2 …] ) 

最先上传:

uploader.upload() 
//uploader.upload( file | fileId)

其他参考:
js猎取剪切板内容,js掌握图片粘贴
在线代码编辑器 CODEMIRROR 事宜申明
javascript.ruanyifeng.com
https://developer.mozilla.org…

    原文作者:xbynet
    原文地址: https://segmentfault.com/a/1190000007434697
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞