1. 程式人生 > >IE6下圖片的瀏覽剪裁與上傳

IE6下圖片的瀏覽剪裁與上傳

最近的一個專案需要實現了一下在IE6下的圖片上傳瀏覽與上傳,查找了不少的資料,終於達到了需求,這裡分享一下解決方法,也為了以後回顧,簡單的Demo在文末有git地址。
簡單的看一下專案的效果:
這裡寫圖片描述
在IE6下實現這個功能主要有一下的幾個問題:

  • IE6不支援onchange事件,所以,如果你簡單的在input框中設定onchange事件,當你選擇圖片之後,是沒有對應的事件監聽的

  • IE6的input框內容是隻讀的,所以,我們無法直接刪除input框的內容

  • IE6不支援ajax FormData,所以我們必須選用其他的方法上傳圖片

  • IE6不支援json,所以對應的後臺介面也要改成字串的格式

瞭解了都有哪些問題,我們就可以著手解決這些問題了。

首先,既然IE6不支援onchange時間,所以,我們就需要找到當IE下的input框內容發生變化的時候,哪個事件被觸發。經過我的查詢,找到了一個IE6下的函式onpropertychange。所以,我們需要給對應的input框繫結這個事件。

function bindOnChange(id) {
        //IE 6 7 繫結事件
        if(!$.support.leadingWhitespace){
            document.getElementById(id).attachEvent('onpropertychange'
, IEunbindOnChange); } else { $("#"+id).change(function (event) { $(this).off(event); showImage(id); }) } }

為了避免多次繫結帶來的種種問題,我這裡是當onpropertychange觸發之後,就解除對應的input的繫結事件。
當偵測到input的內容發生變化的時候,就需要彈出來一個切割框,這裡的切割框我就直接寫在了html下,通過css來控制顯示與隱藏。

<div id="crop-div">
    <div id="crop-container">
        <div id="crop-img-div"></div>
        <div id="btn-group">
            <button id="crop-confirm">確定</button>
            <button id="crop-cancel" style="margin-left: 50px">取消</button>
        </div>
    </div>
</div>

這裡的圖片剪裁的方法是,前臺發過去圖片以及切割的X,Y的位置與目標圖片的大小,具體的切割圖片的操作由後臺程式碼實現。所以前臺就需要傳遞給後臺對應的資訊,我是通過JCrop這個圖片外掛獲取這些資訊,雖然JCrop官網上說值支援到IE7,經過我再IE6下的測試,發現,大部分的功能都是可以使用的,就是選擇框的顯示存在一些問題,所以,我就改了一下JCrop切割框的樣式:

/* Selection Handles */
.jcrop-handle {
  /*background-color: #333333;*/
  /*border: 1px #eeeeee solid;*/
  width: 7px;
  height: 7px;
  font-size: 1px;
}

獲得了需要上傳的圖片以及切割相關引數,那麼我們就需要傳給後臺伺服器了。因為IE6 不支援FormData, 所以我們就無法通過構造FromData的Ajax方式上傳,這裡我們只好通過最原始的動態構造表單的方式上傳我們的資訊。

 var formX = $("<input class='param' name='x' value=" + x + ">");
        var formY = $("<input class='param' name='y' value=" + y + ">");
        var formW = $("<input class='param' name='w' value=" + w + ">");
        var formH = $("<input class='param' name='h' value=" + h + ">");
        var form = $("#form");
        form.attr("enctype","multipart/form-data");
        form.attr("encoding","multipart/form-data");
        formX.appendTo(form);
        formY.appendTo(form);
        formW.appendTo(form);
        formH.appendTo(form);

但是表單上傳不是非同步的而且from返回結果會重新整理當前介面。所以,這裡採用了一個外掛jquery-form,他可以把from表單的結果轉移到它建立的一個frame,從而不會重新整理當前的頁面,而且它還提供了非同步的回撥方法便於我們呼叫。

 var options = {
            url:base_url +"/upload/frame",
            type:"post",
            success:function(data){
                //重置form引數
                formX.remove();
                formY.remove();
                formW.remove();
                formH.remove();
                // IE6返回的內容在<pre>標籤裡面
                if(data.indexOf("<PRE>")!=-1){
                    data = data.replace("<PRE>","");
                    data = data.replace("</PRE>","");
                }
                var res = $.parseJSON(data);
                if(res['code']==0){
                    var src = res["data"];
                    document.getElementById("showImg").src = base_url+'/frameimage/' + src;
                    hideCropDialog("dajiaPic");
                }else{
                    alert("上傳圖片失敗!");
                }
            }
        };
        form.ajaxSubmit(options);

好啦,圖片上傳了,但是為什麼,不是更改下面的img內容而是IE提示要下載一個檔案呢?
這個問題就是IE6不支援json導致的,因為原來的介面返回的是json格式,IE不能識別它所以就會當成一個檔案下載下來,解決方法也只能是把對應的介面為JSON字串就好啦。
到目前為止,我們已經實現了圖片預覽剪裁上傳的基本功能,但是這裡有一個情況:比如我選擇了一張圖片,但是剪裁的範圍不合適,想從新剪裁一次,但是當我再次選擇這張圖片的時候,我們的圖片剪裁框並沒有彈出來。這是為什麼呢,原因是我們這次選擇的圖片還是上次選擇的圖片,也就是input的內容沒有變化,還是以前的那個檔案,所以onpropertychange事件沒有被沒有觸發,但是我們有無法手動的設定input的內容,因為IE6的保護機制不允許更改input框的內容。這裡的解決辦法就是建立一個和以前一模一樣的input框替代現在的input框。

//重置inpur框,並且新增繫結事件
        var newInput = $("<input name='file' type='file' id='"+id+"' accept='image/*'>");
        newInput.on("click",function () {
            bindOnChange(id);
        });

好啦,目前一個基於IE6圖片瀏覽剪裁上傳就完成啦!
我在專案中把圖片處理的提取出來製作一個小的demo,僅供大家交流參考。
專案地址:https://github.com/ArlexDu/IEPictureDemo