最近的一個項目需要實現了一下在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