一般系統(tǒng)的實現(xiàn)方式:
- 代碼實現(xiàn)
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>圖片預(yù)覽</title>
<script src="https://libs.baidu.com/jquery/1.11.3/jquery.min.js"></script>
</head>
<body>
<p>
<img class="img" width="100" height="100" id="previewimg">
</p>
<input class="select" type="file" id="picfile">
<script>
$('.select').change(function(e) {
var _URL = window.URL || window.webkitURL;
$("#previewimg").attr("src", _URL.createObjectURL(this.files[0]))
})
</script>
</body>
</html>
-
input type="file"就是文件選擇標(biāo)簽成福,默認(rèn)樣式為:
如果不喜歡默認(rèn)樣式宜狐,可以把它設(shè)置為透明屠列,然后自己用圖片或元素覆蓋它弱睦,這時候他仍然能響應(yīng)點(diǎn)擊:
opacity: 0;
- multiple="multiple" 屬性可以讓input一次選擇多個文件
- 注冊change監(jiān)聽或定義onChange方法可以在選擇完圖片后回調(diào)踪央,回調(diào)中使用files數(shù)組屬性來獲取選擇的文件臀玄,如果是選擇單文件,files[0]表示選擇的圖片
- jquery回調(diào)中畅蹂,this會自動指向當(dāng)前操作的元素健无,例子中的this和getElementById("picfile")相對,如果要使用jquery方法液斜,可以用$(this)
- oninput事件在元素值發(fā)生變化時立即觸發(fā)累贤, onchange在元素失去焦點(diǎn)時觸發(fā)叠穆,如果是輸入文字,oninput在輸入過程中一直回調(diào)(輸入或刪除一個文字就會調(diào)用一次)畦浓,onchange在輸入完成痹束,點(diǎn)擊其他地方調(diào)用。
- createObjectURL把file對象轉(zhuǎn)為url讓img標(biāo)簽顯示
android系統(tǒng)的實現(xiàn)
安卓webview系統(tǒng)無法通過input打開系統(tǒng)選擇文件框讶请,必須在原生里面攔截webview事件祷嘶,選擇完文件,處理相關(guān)邏輯(比如上傳文件到oss)后回調(diào)到webview
wvmain.setWebChromeClient(new WebChromeClient(){
//For Android >= 5.0
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
uploadMessageAboveL = filePathCallback;
uploadPicture();
return true;
}
//For Android >= 4.1
public void openFileChooser(ValueCallback<Uri> valueCallback, String acceptType, String capture) {
uploadMessage = valueCallback;
uploadPicture();
}
});
- android依靠uploadMessageAboveL/uploadMessage回調(diào)向webview回傳圖片uri等信息
- android在uploadPicture里調(diào)用原生方法彈出原生圖片選擇框夺溢,點(diǎn)擊選擇圖片后论巍,得到所選擇的圖片uri,上傳到oss
- 處理完文件上傳后风响,調(diào)用Callback(valueCallback 或 filePathCallback)的onReceiveValue方法嘉汰,webview里的input標(biāo)簽才會調(diào)用onchange
比如以下是選擇完文件后,上傳文件到oss成功后的回調(diào)里状勤,如果成功得到oss圖片地址鞋怀,則調(diào)用onReceiveValue方法把圖片的本地uri回傳給webview,失敗或異常情況回傳null給webview
public void successImg(String img_url) {
if (img_url != null){
curPicUrl = img_url;
mHandle.sendEmptyMessage(UPLOAD_SUCESS);
if (uploadMessage != null) {
uploadMessage.onReceiveValue(imageUri);
uploadMessage = null;
}
if (uploadMessageAboveL != null) {
uploadMessageAboveL.onReceiveValue(new Uri[]{imageUri});
uploadMessageAboveL = null;
}
}else{
curPicUrl = "";
mHandle.sendEmptyMessage(UPLOAD_FAIL);
if (uploadMessage != null) {
uploadMessage.onReceiveValue(null);
uploadMessage = null;
}
if (uploadMessageAboveL != null) {
uploadMessageAboveL.onReceiveValue(null);
uploadMessageAboveL = null;
}
}
}
- 如果回傳null給webview持搜,如果input里面之前還沒有文件密似, input的onchange,oninput方法不會調(diào)用葫盼,如果之前已經(jīng)選擇過文件残腌,files對象之前里面有內(nèi)容,現(xiàn)在內(nèi)容會變成空贫导,發(fā)生了改變,onchange抛猫,oninput方法都會調(diào)用(先調(diào)用oninput),但是files對象的長度為0孩灯,可以根據(jù)files的長度來做不同的處理闺金,比如:
doChange() {
var file = document.getElementById("fileInput");
if(file.files.length == 0){//清除之前的圖片
document.getElementById("showpic" + i).style.display = "none";
return;
}else{
//顯示圖片預(yù)覽
}
}