div中粘貼圖片並上傳服務器 div中拖拽圖片文件並上傳服務器

應用簡介:此文主要是描述如何在前端div中直接ctrl+v 粘貼圖片,並上傳到服務器,包括拖拽圖片文件到div中html

應用場景描述:用QQ或者其它切圖軟件截圖,在指定的div中ctrl+v 粘貼並顯示,點擊上傳按鈕,圖片上傳到服務器。相似實現了此功能的網站有 知乎 強力建議博客園實現此功能,寫博客時插入圖片方便的多。前端

適用環境:本代碼目前適用谷歌瀏覽器、火狐,其它瀏覽器須要稍微改良一下便可,問題不大。node

開發環境:vs2015 mvc web

不說廢話了,開始吧:ajax

 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上傳圖片數據mvc

    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後臺,根據本身的語言不通採用對應的處理方式app

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);
    }
相關文章
相關標籤/搜索