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