zoukankan      html  css  js  c++  java
  • HTML5 CSS3 经典案例:无插件拖拽上传图片 (支持预览与批量) (二)

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/31513065

    上一篇已经实现了这个项目的整体的HTML和CSS:

    HTML5 CSS3 经典案例:无插件拖拽上传图片 (支持预览与批量) (一)

    这篇博客直接在上篇的基础上完成,最终效果:

    效果图1:


    效果图2:

    好了,请允许我把图片贴了两遍,方便大家看效果了~

    可以看出我们的图片的li的html其实还是挺复杂的,于是我把html文档做了一些修改:

    <span style="font-size:12px;"><body>
    
    <div id="uploadBox">
    </div>
    
    <div id="template" class="hidden">
        <li>
            <img src=""/>
            <span class="progress"></span>
            <span class="percentage"></span>
        </li>
    </div>
    </body></span>
    可以看到我把li的显示,独立写到了一个div#template,默认是hidden的,这样做的好处是什么呢?避免我们每上传一个文件,在js中出现大量的创建元素与赋属性的代码,一般设计比较复杂的html元素的生成,建议使用这种方式,可以简化代码,也利于我们代码的后期维护。

    Js代码:

    <span style="font-size:12px;">/**
     * User: zhy
     * Date: 14-6-16
     * Time: 下午11:06
     */
    var ZhangHongyang = {};
    ZhangHongyang.html5upload = (function ()
    {
        var _ID_UPLOAD_BOX = "uploadBox";
        var _CLASS_PROGRESS = "progress";
        var _CLASS_PERCENTAGE = "percentage";
    
        var _tip_no_drag = "将文件拖拽至此区域,即可上传!";
        var _tip_drag_over = "释放鼠标立即上传!";
    
        var _uploadEle = null;
    
        /**
         * 初始化对象与事件
         * @private
         */
        function _init()
        {
            _uploadEle = document.getElementById(_ID_UPLOAD_BOX);
            _uploadEle.ondragenter = _onDragEnter;
            _uploadEle.ondragover = _onDragOver;
            _uploadEle.ondragleave = _onDragLeave;
            _uploadEle.ondrop = _onDrop;
            _setStatusNoDrag();
    
        };
    
    
        /**
         * 正在拖拽状态
         * @private
         */
        function _setDragOverStatus()
        {
            if (_checkContatinsElements())return;
            _uploadEle.innerText = _tip_drag_over;
            _uploadEle.style.border = "2px dashed #777";
            $(_uploadEle).css({lineHeight: $(_uploadEle).height() + "px"});
        }
    
        /**
         * 初始化状态
         * @private
         */
        function _setStatusNoDrag()
        {
            if (_checkContatinsElements())return;
            _uploadEle.innerText = _tip_no_drag;
            _uploadEle.style.border = "2px dashed #777";
            $(_uploadEle).css({lineHeight: $(_uploadEle).height() + "px"});
        }
    
        /**
         * 上传文件
         * @private
         */
        function _setDropStatus()
        {
    
            if (_checkContatinsElements())return;
            _uploadEle.innerText = "";
            _uploadEle.style.border = "1px solid #444";
            $(_uploadEle).css({lineHeight: "1em"});
            $(_uploadEle).append("<ul></ul>");
    
        };
    
    
        /**
         * 判断是否已经上传文件了
         * @private
         */
        function _checkContatinsElements()
        {
            return !!$(_uploadEle).find("li").size();
    
        }
        /**
         * 当ondragenter触发
         * @private
         */
        function _onDragEnter(ev)
        {
            _setDragOverStatus();
        }
        /**
         * 当ondargmove触发
         * @private
         */
        function _onDragOver(ev)
        {
            //ondragover中必须组织事件的默认行为,默认地,无法将数据/元素放置到其他元素中。
            ev.preventDefault();
    
        }
        /**
         * 当dragleave触发
         * @private
         */
        function _onDragLeave(ev)
        {
            _setStatusNoDrag();
        }
    
        /**
         * ondrop触发
         * @private
         */
        function _onDrop(ev)
        {
            //drop 事件的默认行为是以链接形式打开,所以也需要阻止其默认行为。
            ev.preventDefault();
            _setDropStatus();
    
            //拿到拖入的文件
            var files = ev.dataTransfer.files;
            var len = files.length;
            for (var i = 0; i < len; i++)
            {
                //页面上显示需要上传的文件
                _showUploadFile(files[i]);
            }
        }
        /**
         * 页面上显示需要上传的文件
         * @private
         */
        function _showUploadFile(file)
        {
            var reader = new FileReader();
    //        console.log(file)
    //        console.log(reader);
    
            //判断文件类型
            if (file.type.match(/image*/))
            {
                reader.onload = function (e)
                {
                    var formData = new FormData();
    
                    var li = $("#template li").clone();
                    var img = li.find("img");
                    var progress = li.find(".progress");
                    var percentage = li.find(".percentage");
                    percentage.text("0%");
                    img.attr("src", e.target.result);
                    $("ul", $(_uploadEle)).append(li);
                    $(_uploadEle).find("li").size() == 10 && $(_uploadEle).width(($(_uploadEle).width() + 8) + "px").css("overflow", "auto");
                    formData.append("uploadFile", file);
    
                    //上传文件到服务器
                    _uploadToServer(formData, li, progress, percentage);
    
                };
                reader.readAsDataURL(file);
            }
            else
            {
                console.log("此" + file.name + "不是图片文件!");
            }
        }
    
        /**
         * 上传文件到服务器
         * @private
         */
        function _uploadToServer(formData, li, progress, percentage)
        {
            var xhr = new XMLHttpRequest();
            xhr.open("POST", "http://localhost:8080/strurts2fileupload/uploadAction", true);
            xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest', 'Content-Type', 'multipart/form-data;');
    
            //HTML5新增的API,存储了上传过程中的信息
            xhr.upload.onprogress = function (e)
            {
                var percent = 0;
                if (e.lengthComputable)
                {
                    //更新页面显示效果
                    percent = 100 * e.loaded / e.total;
                    progress.height(percent );
                    percentage.text(percent + "%");
                    percent >= 100 && li.addClass("done");
                }
            };
            xhr.send(formData);
        }
    
    
        //把init方法公布出去
        return{
            init: _init }
    
    
    })();
    </span>

    注释写得很详细,这次没有直接使用字面量创建对象,因为我不希望使用者可以访问所有的方式和变量,使用了简单的闭包,可以看出几乎所有的方法和变量都是_开头,是因为我认为它们是私有的,我也没有公布出来,唯一公布的就是init方法,供使用者调用。整体方法也使用了命名空间,这样和其他伙伴写的js基本不做造成变量相同的问题。

    上面的js中用到了HTML FileApi,这里介绍一下:

    1、File对象也就是我们上面使用的:
    File
    1. lastModifiedDateThu Dec 26 2013 18:45:08 GMT+0800 (中国标准时间)
    2. name"yt_key.png"
    3. size45524
    4. type"image/png"
    5. webkitRelativePath""
    6. __proto__File
    可以看到包含上面的一些属性,也就是说,如果使用支持html5的浏览器,给input=type设置onchange事件,用户选择图片或者文件后,就可以做出图片的显示或者文件大小和类型的判断。

    2、FileReader主要用于异步读取文件内容,注意是异步的,上例我们使用了它的readAsDataURL的方法,关于DataUri的知识可以自己去百度下。
    另外还提供了:readAsText用于读取文本;readAsArrayBuffer和readAsBinaryString方法;
    还提供了一些事件:onloadstart, onload, onprogress ,onerror , onloaded , onabort 有兴趣的可以去一个一个查看。

    最后页面调用,大功告成:

    <span style="font-size:12px;">    <script type="text/javascript" src="jquery-1.8.3.js"></script>
        <script type="text/javascript" src="js/html5upload.js"></script>
    
        <script type="text/javascript">
    
            window.onload = function ()
            {
                ZhangHongyang.html5upload.init();
            }
            ;
    
        </script></span>




    欢迎大家指点~


    源码点击下载



    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    Docker 文档编译
    Docker CentOS 安装方法
    Docker CentOS 安装要求
    Docsify 的文档页面标题在那里设置
    Docsify 的 GitHub 链接在那里设置的
    GitHub 中如何启用 GitHub Pages 中的子域名
    Spring API 的 CORS 测试 提示错误 Reason: header ‘authorization’ is not allowed
    Spring API 的 CORS 测试
    CentOS 7 安装 JDK 11
    Postman API 获得文件如何保存
  • 原文地址:https://www.cnblogs.com/dingxiaoyue/p/4924935.html
Copyright © 2011-2022 走看看