div中粘贴图片并上传服务器 div中拖拽图片文件并上传服务器

应用简介:此文主要是描述如何在前端div中直接ctrl+v 粘贴图片,并上传到服务器,包括拖拽图片文件到div中

应用场景描述:用QQ或者其它切图软件截图,在指定的div中ctrl+v 粘贴并显示,点击上传按钮,图片上传到服务器。类似实现了此功能的网站有 知乎 强力建议博客园实现此功能,写博客时插入图片方便的多。

适用环境:本代码目前适用谷歌浏览器、火狐,其它浏览器需要稍微改良一下即可,问题不大。

开发环境:vs2015 mvc 

不说废话了,开始吧:

 1:首先创建HTML元素,我们要粘贴的图片就是显示在 id=pasteImg 的div里面,注意 需要设置div的 contenteditable="true" 属性才可以编辑哦。

<div id="pasteImg" style="width:400px;height:300px;border:dashed" contenteditable="true"></div>
<button style="width:30px;height:20px;" id="btnGO">上传图片</button>

2:写js代码:绑定粘贴事件 上传图片服务器

 window.onload = function () {

        function paste_img(e) {

            if (e.clipboardData && e.clipboardData.items) {

                var imageContent = e.clipboardData.getData('image/png');
                ele = e.clipboardData.items
                for (var i = 0; i < ele.length; ++i) {
//粘贴图片
if (ele[i].kind == 'file' && ele[i].type.indexOf('image/') !== -1) { var blob = ele[i].getAsFile(); window.URL = window.URL || window.webkitURL; var blobUrl = window.URL.createObjectURL(blob); // 显示到div中,此时是显示的本地图片数据,并没有上传到服务器 var new_img = document.createElement('img'); new_img.setAttribute('src', blobUrl); new_img.setAttribute('blobdata', blob);
// 移动div光标到新元素后面 insertHtmlAtCaret(new_img);
// 直接上传,当然你也可以不在这上传,可以点击按钮在上传
  uploadImg(blob);
}
//粘贴文本
else if (ele[i].kind === "string" && ele[i].type.indexOf('text/plain') != -1) {
                        //粘贴文本回调函数
ele[i].getAsString(
                                function (str) {
                                insertHtmlAtCaret(document.createTextNode(str));//插入文本到光标处 并移动光标到新位置
                        })

                    }
                    else return;

                }


            }
            else {
                alert('不支持的浏览器');
            }
        }
//绑定粘贴事件 document.getElementById(
'pasteImg').onpaste = function () { paste_img(event); return false; };
}

3:下面是insertHtmlAtCaret方法,主要实现在div移动光标的位置,用不上的直接跳过此步骤

//聊天内容框 插入文本或者其他元素后,移动置光标到最新处
function insertHtmlAtCaret(childElement) {
    var sel, range;
    if (window.getSelection) {
        // IE9 and non-IE
        sel = window.getSelection();
        if (sel.getRangeAt && sel.rangeCount) {
            range = sel.getRangeAt(0);
            range.deleteContents();

            var el = document.createElement("div");
            el.appendChild(childElement);
            var frag = document.createDocumentFragment(), node, lastNode;
            while ((node = el.firstChild)) {
                lastNode = frag.appendChild(node);
            }

            range.insertNode(frag);
            if (lastNode) {
                range = range.cloneRange();
                range.setStartAfter(lastNode);
                range.collapse(true);
                sel.removeAllRanges();
                sel.addRange(range);
            }
        }
    }
    else if (document.selection && document.selection.type != "Control") {
        // IE < 9
        //document.selection.createRange().pasteHTML(html);
    }
}

4:采用XHR上传图片数据

    var createStandardXHR = function () {
        try {
            return new window.XMLHttpRequest();
        } catch (e) {
            return false;
        }
    };
    var createActiveXHR = function () {
        try {
            return new window.ActiveXObject("Microsoft.XMLHTTP");
        } catch (e) {
            return false;
        }
    };

    var xhr;

    function createXHR() {
        var temp = createStandardXHR() || createActiveXHR();

        if (window.XDomainRequest === undefined) {
            return temp;
        } else {
            return new XDomainRequest();
        }
    }
    //前端上传方法
    function uploadImg(obj) {

        xhr = createXHR();
        if (xhr) {
            xhr.onerror = err;
            xhr.ontimeout = timeo;
            xhr.onprogress = progres;
            xhr.onload = loadd;
            xhr.timeout = timeo;

        }
        else {
            alert("Failed to create");
        }

        //发送的数据
        var fd = new FormData();
        fd.append("image", obj, "imgtest.png");

        //使用ajax发送
        xhr.open('POST', '/Home/uploadFun', true);//第二个参数是服务器处理action,各个语言提供方式不一样,我这是.net mvc 后台处理的,具体方法见步骤5
        xhr.send(fd);
    }

    function err() {
        // alert("XDR onerror");
    }

    function timeo() {
        // alert("XDR ontimeout");
    }

    function loadd() {
        //  alert("上传完成");
        // alert("Got: " + xhr.responseText);
    }

    function progres() {
        //alert("XDR onprogress");
    }

    function stopdata() {
        xhr.abort();
    }

5:后台接收图片数据处理方法,本人采用 .net MVC后台,根据自己的语言不通采用对应的处理方式

public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

     
        [HttpPost]
        public ActionResult uploadFun()
        {
            if (Request.Files.Count > 0)
            {
                var file = Request.Files[0];
                if (file != null && file.ContentLength > 0)
                {
                    //验证文件格式
                    var extension = Path.GetExtension(file.FileName);
                    //if (extension != ".xls" && extension != ".xlsx")
                    //{
                    //}

//上传成功的图片URL var fileFullPath = Path.Combine(Request.MapPath("~/uploads"), DateTime.Now.ToString("yyyyMMddHHmmss") + Path.GetFileName(file.FileName)); file.SaveAs(fileFullPath); return Content("上传成功!url:"+fileFullPath , "text/plain");
}
}

returnnew JsonResult();
}
}

6:扩展一下,拖拽图片文件到div 直接发送

//以下是拖拽事件
document.addEventListener("dragenter", function (e) {
    e.stopPropagation();
    e.preventDefault();
}, false);
document.addEventListener("dragleave", function (e) {
    e.stopPropagation();
    e.preventDefault();
}, false);

document.addEventListener("dragover", function (e) {
    e.stopPropagation();
    e.preventDefault();
}, false);
document.addEventListener("drop", function (e) {
    e.stopPropagation();
    e.preventDefault();

    handleFiles(e.dataTransfer.files);

}, false);

//拖拽文件处理事件
handleFiles = function (files) {
    for (var i = 0; i < files.length; i++) {
        var file = files[i];

        //如果拖住进来的是图片文件则显示
        if (file.type.match(/image*/)) {
            $("#pasteImg").focus();
            var blob =file; 
window.URL = window.URL || window.webkitURL;
var blobUrl = window.URL.createObjectURL(blob); // 显示到div中,此时是显示的本地图片数据,并没有上传到服务器
var new_img = document.createElement('img');
new_img.setAttribute('src', blobUrl);
new_img.setAttribute('blobdata', blob);
            // 移动div光标到新元素后面
            insertHtmlAtCaret(new_img);
// 直接上传,当然你也可以不在这上传,可以点击按钮在上传
  uploadImg(blob);
} else { continue; } } }

7:至此就实现了ctrl+v 粘贴图片并发送服务器,也具有拖拽图片文件 并发送服务器的功能

发散:可以做文件上传的东西

待解决:IE浏览器和火狐浏览器可以直接粘贴图片及文件,显示的是数据而不是blob格式而已

这是隔日再来写的,以下是火狐浏览器解决方法,已亲测,可行,只不过,火狐不要写粘贴事件,它已自带

document.getElementById('btnGO').onclick = function () {
          
            var img = $("#pasteImg").find('img').eq(0);
            var blob = dataURLtoBlob(img.attr('src'));
            //上传方法
            uploadImg(blob);

        };

   //**dataURL to blob**
    function dataURLtoBlob(dataurl) {
        var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
            bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
        while (n--) {
            u8arr[n] = bstr.charCodeAt(n);
        }
        return new Blob([u8arr], { type: mime });
    }

    //**blob to dataURL**
    function blobToDataURL(blob, callback) {
        var a = new FileReader();
        a.onload = function (e) { callback(e.target.result); }
        a.readAsDataURL(blob);
    }

 

posted @ 2016-05-16 19:38  flyArmy  阅读(6106)  评论(1编辑  收藏  举报