仿淘宝头像上传功能(三)——兼容 IE6 浏览器。

前两篇目录:

仿淘宝头像上传功能(一)——前端篇。

仿淘宝头像上传功能(二)——程序篇

 仿淘宝头像上传功能(三)——兼容 IE6 浏览器

之前的这两篇虽然实现了功能,但不兼容低版本浏览器,而且有些浏览器还会死机,所以现在重新做了个新的。

现已在 IE6,IE10,IE11,谷歌测试通过。

这次使用了这两个插件:

Jquery:1.11.2

上图文件插件:ajaxFileUpload

裁剪插件:imgAreaSelect

1.文件上传需要使用到 file 表单,但 file 表单样式太难看,需要进行自定义。

由于在IE下需要手动点击 file 表单才有效果,所以,无法使用 onclick 事件!!

解决办法就是使用样式,覆盖在 file 表单上传,当点击该样式的时候,实际上点击的是 file 表单

2.ajaxFileUpload 插件的各种版本太多,这里给出自己使用的一个版本。

先直接给出JS源码了:

////////////////////////////////////////////////////////////////
// 上传头像JS
//上传头像插件:ajaxFileUpload
//裁剪插件:imgAreaSelect
///////////////////////////////////////////////////////////////

//上传文件按钮表单 ID。
var inputFileId = "fileupload_input";

//原图片显示 ID。
var sourceImageId = "photo";

//裁剪大图显示 ID。
var bigImageId = "cut1";

//裁剪中图显示 ID。
var centerImageId = "cut2";

//裁剪小图显示 ID。
var smallImageId = "cut3";

//临时图片(隐藏)。
var hiddenImage = "test";

//保存裁剪框左上角 X 坐标的表单。
var inputX = "X";

//保存裁剪框左上角 Y 坐标的表单。
var inputY = "Y";

//保存裁剪框宽度的表单。
var inputWidth = "Width";

//保存裁剪框高度的表单。
var inputHeight = "Height";

//提交按钮表单。
var submitButtonId = "btnAjaxSubmit";

//上传图片文件 URL。
var fileUploadUrl = "/user/icon/upload";

//提交裁剪坐标信息并保存图片的 URL。
var submitUrl = "/user/upload";

var hasFile = false;
var isSelect = false;
var imgArea = null;

//初始化选择控件
function InitSelect() {
    imgArea = $('#' + sourceImageId).imgAreaSelect({
        x1: 0, y1: 0, x2: 10, y2: 10,
        maxWidth: 300,
        maxHeight: 300,
        aspectRatio: '1:1',

        instance: true,
        persistent: true,
        //resizable: true,
        show: true,

        handles: true,
        onSelectEnd: preview
    });
}

function preview(img, selection) {
    //获取图片链接到缩略图
    var cut1 = $("#" + bigImageId);
    var cut2 = $("#" + centerImageId);
    var cut3 = $("#" + smallImageId);
    Zoom(img, cut1, selection, 180, 180);
    Zoom(img, cut2, selection, 50, 50);
    Zoom(img, cut3, selection, 30, 30);

    isSelect = true;

    $("#" + inputX).val(selection.x1);
    $("#" + inputY).val(selection.y1);
    $("#" + inputWidth).val(selection.width);
    $("#" + inputHeight).val(selection.height);

    CleanDisabled();
}

//缩放预览
function Zoom(source, imgCut, selection, X, Y) {
    var imgurl = $(source).attr("src");
    var sWidth = $(source).width();
    var sHight = $(source).height();

    $(imgCut).attr("src", imgurl);

    var scaleX = X / (selection.width || 1);
    var scaleY = Y / (selection.height || 1);

    $(imgCut).css({
         Math.round(scaleX * sWidth) + 'px',
        height: Math.round(scaleY * sHight) + 'px',
        marginLeft: '-' + Math.round(scaleX * selection.x1) + 'px',
        marginTop: '-' + Math.round(scaleY * selection.y1) + 'px'
    });
}

//重设原图宽高
function resetImg() {
    try {
        var source = $("#" + sourceImageId);
        var sWidth = $("#" + hiddenImage).width();
        var sHight = $("#" + hiddenImage).height();

        if (sWidth > sHight) {
            $(source).attr("width", 300);
            $(source).removeAttr("height");
        }
        else {
            $(source).attr("height", 300);
            $(source).removeAttr("width");
        }
    }
    catch (ex) {
        //showErr("截图程序异常");
    }
}

//默认图片选择区域
function setDefault_Selection() {
    var x = $("#" + hiddenImage).width();
    var y = $("#" + hiddenImage).height();

    var scale = 0.0;
    var x1, y1, x2, y2 = 0;
    if (x > y) {
        scale = 300 / x;
        x = 300;
        y = scale * y;
    }
    else {
        scale = 300 / y;
        y = 300;
        x = scale * x;
    }

    var rx = x / 2;
    var ry = y / 2;
    var length = 70;

    x1 = rx - length; y1 = ry - length;
    x2 = rx + length, y2 = ry + length;

    imgArea.setSelection(x1, y1, x2, y2);
    imgArea.update();

    preview($("#" + sourceImageId), imgArea.getSelection());
}

//图片上传预览
function previewImage(file) {
    ////只有高版本浏览器可用,可以直接使用本地图片预览。
    //if (file.files && file.files[0]) {
    //    if (file.files[0].type != "image/jpeg") {
    //        showErr("仅支持JPG图片文件,且文件小于3M");
    //        return;
    //    }

    //    if (file.files[0].size > 3145728) {
    //        showErr("仅支持JPG图片文件,且文件小于3M");
    //        $(file).attr("src", "");
    //        return;
    //    }

    //    var img = document.getElementById('photo');
    //    var reader = new FileReader();
    //    reader.onload = function (evt) {
    //        img.src = evt.target.result;
    //        $("#test").attr("src", evt.target.result);

    //        //延迟加载
    //        setTimeout(function () {
    //            hasFile = true;
    //            resetImg();
    //            InitSelect();
    //            setDefault_Selection();
    //        }, 200);
    //    }
    //    reader.readAsDataURL(file.files[0]);
    //}
    //else
    //    return;

    /*低版本浏览器兼容*/
    var selection = $("#" + sourceImageId).imgAreaSelect({ instance: true }).getSelection();
    $.ajaxFileUpload({
        url: fileUploadUrl,
        secureuri: false,
        fileElementId: inputFileId,              //文件上传域的ID
        data: selection,
        dataType: 'json',
        success: function (data, status)      //服务器成功响应处理函数
        {
            imgClear();

            //图片上传成功后,返回包含原图 URL 的 Json 对象。
            $("#" + sourceImageId).attr("src", data.Image + "?num=" + Math.random());
            $("#" + hiddenImage).attr("src", data.Image);

            //延迟加载
            setTimeout(function () {
                hasFile = true;
                resetImg();
                InitSelect();
                setDefault_Selection();
            }, 200);
        },
        error: function (data, status, e) {
            //showErr("头像加载失败,请重试或者联系管理员");
        }
    });
}

function imgClear() {
    $("#" + sourceImageId).attr("style", "");
    $("#" + sourceImageId).attr("src", "");
    $("#" + bigImageId).attr("src", "");
    $("#" + centerImageId).attr("src", "");
    $("#" + smallImageId).attr("src", "");
}

//取消禁用。
function CleanDisabled() {
    $("#" + submitButtonId).removeAttr("style");
    $("#" + submitButtonId).removeAttr("disabled");
}

//禁用按钮。
function SetDisabled() {
    $("#" + submitButtonId).attr("style", "background-color:#f39898;");
    $("#" + submitButtonId).attr("disabled", "disabled");
}

$("#" + submitButtonId).click(function () {
    $.ajax({
        type: "POST",
        url: submitUrl,
        data: $(this).parent().serialize(),
        dataType: 'json',
        success: function (data) {
            if (data.Status > 0) {
                //showSuc("头像上传成功!");
                //$("#currentIcon").attr("src", data.BigIcon);
                //$("#nav-top-icon").attr("src", data.SmallIcon);
            }
        },
        error: function () {
            //showErr("头像上传异常,请重试或者联系管理员");
        }
    });
});
View Code

HTML:

<div class="boxbar headbox">
    <div class="title">修改头像</div>
    <div class="content">
        <div class="upload_btn">
            <form id="fm" method="post" action="/user/icon/upload" enctype="multipart/form-data">
                <span id="fileupload-content" class="btn_sc">
                    <span>上传本地相片</span>
                    <input type="file" id="fileupload_input" name="fileInput" onchange="previewImage(this);" />
                </span>
            </form>
            <span class="tip">仅支持JPG图片文件,且文件小于3M</span>
            <img id="test" src="" hidden="hidden" style="display: none;" />
        </div>
        <div class="pic_box">
            <div id="img-preview" class="pic_left" style="overflow: hidden;position:relative;">
                <img id="photo" src="" />
            </div>
            <div class="pic_line"></div>
            <div class="pic_con">
                <p class="tip">您上传的头像会自动生成三种尺寸,请注意中小尺寸的头像是否清晰</p>
                <div id="preview_box_200" class="big_pic" style="overflow: hidden;position:relative;">
                    <img id="cut1" style="position: relative;" />
                </div>
                <div class="pic_cc">大头像尺寸,180x180像素</div>
            </div>
            <div class="pic_right">
                <div id="preview_box_50" class="midd_pic" style="overflow: hidden;position:relative;">
                    <img id="cut2" style="position: relative;  50px; height: 50px;" src="" />
                </div>
                <div class="pic_cc">
                    中尺寸头像50x50像素
                    <p>(自动生成)</p>
                </div>
                <div id="preview_box_small" class="small_pic" style="overflow: hidden;position:relative;">
                    <img id="cut3" style="position: relative;  30px; height: 30px;" />
                </div>
                <div class="pic_cc">
                    小尺寸头像30x30像素
                    <p>(自动生成)</p>
                </div>
            </div>
        </div>
        <form id="userIconForm" method="POST">
            <input id="X" name="X" type="hidden" />
            <input id="Y" name="Y" type="hidden" />
            <input id="Width" name="Width" type="hidden" />
            <input id="Height" name="Height" type="hidden" />
            <button id="btnAjaxSubmit" class="btn_tj" type="button" style="background-color:#f39898" disabled="disabled">&nbsp;&nbsp;</button>
        </form>
    </div>
</div>
View Code

这里给出使用的插件源码

ajaxFileUpload

jQuery.extend({
    createUploadIframe: function (id, uri) {
        //create frame
        var frameId = 'jUploadFrame' + id;
        var iframeHtml = '<iframe id="' + frameId + '" name="' + frameId + '" style="position:absolute; top:-9999px; left:-9999px"';
        if (window.ActiveXObject) {
            if (typeof uri == 'boolean') {
                iframeHtml += ' src="' + 'javascript:false' + '"';
            }
            else if (typeof uri == 'string') {
                iframeHtml += ' src="' + uri + '"';
            }
        }
        iframeHtml += ' />';
        jQuery(iframeHtml).appendTo(document.body);

        return jQuery('#' + frameId).get(0);
    },
    createUploadForm: function (id, fileElementId, data) {
        //create form
        var formId = 'jUploadForm' + id;
        var fileId = 'jUploadFile' + id;
        var form = jQuery('<form  action="" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>');
        if (data) {
            for (var i in data) {
                jQuery('<input type="hidden" name="' + i + '" value="' + data[i] + '" />').appendTo(form);
            }
        }
        var oldElement = jQuery('#' + fileElementId);
        var newElement = jQuery(oldElement).clone();
        jQuery(oldElement).attr('id', fileId);
        jQuery(oldElement).before(newElement);
        jQuery(oldElement).appendTo(form);

        //set attributes
        jQuery(form).css('position', 'absolute');
        jQuery(form).css('top', '-1200px');
        jQuery(form).css('left', '-1200px');
        jQuery(form).appendTo('body');
        return form;
    },

    ajaxFileUpload: function (s) {
        // TODO introduce global settings, allowing the client to modify them for all requests, not only timeout
        s = jQuery.extend({}, jQuery.ajaxSettings, s);
        var id = new Date().getTime()
        var form = jQuery.createUploadForm(id, s.fileElementId, (typeof (s.data) == 'undefined' ? false : s.data));
        var io = jQuery.createUploadIframe(id, s.secureuri);
        var frameId = 'jUploadFrame' + id;
        var formId = 'jUploadForm' + id;
        // Watch for a new set of requests
        if (s.global && !jQuery.active++) {
            jQuery.event.trigger("ajaxStart");
        }
        var requestDone = false;
        // Create the request object
        var xml = {}
        if (s.global)
            jQuery.event.trigger("ajaxSend", [xml, s]);
        // Wait for a response to come back
        var uploadCallback = function (isTimeout) {
            var io = document.getElementById(frameId);
            try {
                if (io.contentWindow) {
                    xml.responseText = io.contentWindow.document.body ? io.contentWindow.document.body.innerHTML : null;
                    xml.responseXML = io.contentWindow.document.XMLDocument ? io.contentWindow.document.XMLDocument : io.contentWindow.document;
                } else if (io.contentDocument) {
                    xml.responseText = io.contentDocument.document.body ? io.contentDocument.document.body.innerHTML : null;
                    xml.responseXML = io.contentDocument.document.XMLDocument ? io.contentDocument.document.XMLDocument : io.contentDocument.document;
                }
            } catch (e) {
                jQuery.handleError(s, xml, null, e);
            }
            if (xml || isTimeout == "timeout") {
                requestDone = true;
                var status;
                try {
                    status = isTimeout != "timeout" ? "success" : "error";
                    // Make sure that the request was successful or notmodified
                    if (status != "error") {
                        // process the data (runs the xml through httpData regardless of callback)
                        var data = jQuery.uploadHttpData(xml, s.dataType);
                        // If a local callback was specified, fire it and pass it the data
                        if (s.success)
                            s.success(data, status);

                        // Fire the global callback
                        if (s.global)
                            jQuery.event.trigger("ajaxSuccess", [xml, s]);
                    } else
                        jQuery.handleError(s, xml, status);
                } catch (e) {
                    status = "error";
                    jQuery.handleError(s, xml, status, e);
                }

                // The request was completed
                if (s.global)
                    jQuery.event.trigger("ajaxComplete", [xml, s]);

                // Handle the global AJAX counter
                if (s.global && ! --jQuery.active)
                    jQuery.event.trigger("ajaxStop");

                // Process result
                if (s.complete)
                    s.complete(xml, status);

                jQuery(io).unbind()

                setTimeout(function () {
                    try {
                        jQuery(io).remove();
                        jQuery(form).remove();
                    } catch (e) {
                        jQuery.handleError(s, xml, null, e);
                    }
                }, 100)

                xml = null
            }
        }
        // Timeout checker
        if (s.timeout > 0) {
            setTimeout(function () {
                // Check to see if the request is still happening
                if (!requestDone) uploadCallback("timeout");
            }, s.timeout);
        }
        try {
            var form = jQuery('#' + formId);
            jQuery(form).attr('action', s.url);
            jQuery(form).attr('method', 'POST');
            jQuery(form).attr('target', frameId);
            if (form.encoding) {
                jQuery(form).attr('encoding', 'multipart/form-data');
            }
            else {
                jQuery(form).attr('enctype', 'multipart/form-data');
            }
            jQuery(form).submit();

            //提交file域值不清空(原理:提交后把对象再复制回来,达到不清空的目的)
            var oldElement = jQuery('#jUploadFile' + id, form);
            var newElement = jQuery('#' + s.fileElementId);
            jQuery(newElement).replaceWith(oldElement);
            jQuery(oldElement).attr('id', s.fileElementId);
        } catch (e) {
            jQuery.handleError(s, xml, null, e);
        }

        jQuery('#' + frameId).load(uploadCallback);
        return { abort: function () { } };
    },

    //修正JQ1.6以上版本去除handleError的BUG
    handleError: function (s, xhr, status, e) {
        if (s.error) {
            s.error.call(s.context || s, xhr, status, e);
        }
        if (s.global) {
            (s.context ? jQuery(s.context) : jQuery.event).trigger("ajaxError", [xhr, s, e]);
        }
    },

    uploadHttpData: function (r, type) {
        var data = !type;
        data = type == "xml" || data ? r.responseXML : r.responseText;
        // If the type is "script", eval it in global context
        if (type == "script")
            jQuery.globalEval(data);
        // Get the JavaScript object, if JSON is used.
        //修正一直提示ERROR的BUG type==json
        if (type == "json")
            //eval("data = " " + data + " " ");
            eval("data = " + data);
        // evaluate scripts within html
        if (type == "html")
            jQuery("<div>").html(data).evalScripts();

        return data;
    }
})
View Code
原文地址:https://www.cnblogs.com/cjnmy36723/p/4778548.html