時間:2023-05-21 11:40:02 | 來源:網(wǎng)站運營
時間:2023-05-21 11:40:02 來源:網(wǎng)站運營
從微信H5點擊保存圖片說起:微信H5里保存圖片,大都是通過長按操作,彈起actionsheet保存照片。但我們的部分用戶是老年群體,不知道怎么進行“長按”操作??紤]到這個因素,產(chǎn)品要求實現(xiàn)點擊保存按鈕來保存圖片。<a href="me.png" download="me"></a>
但在使用前,需要考慮下兩個問題:跨域問題和兼容問題。var hasDownloadAttribute = 'download' in document.createElement('a')
將該腳本加在網(wǎng)頁里,并在微信環(huán)境打開,運行結(jié)果居然是"true"。import axios from 'axios';import download from 'downloadjs'; axios.get(someUrl, { responseType: 'blob'}).then(res => { download(res.data, "awesome.png", "image/png");})
先講結(jié)論,同方案1一樣,只是解決了兼容性問題,但無法調(diào)起微信app保存圖片的能力。const saver = (url, mimeType) => { // 如果支持download屬性 if ('download' in anchor) { anchor.href = url; anchor.style.display = 'none'; document.body.appendChild(anchor); setTimeout(() => { anchor.click(); document.body.removeChild(anchor); setTimeout(() => { // 釋放通過createObjectURL創(chuàng)建的URL window.URL.revokeObjectUrl(blob); }, 250) }, 100) return; } // 兼容不支持download屬性的部分Safari瀏覽器 if (/(Version)//(/d+)/.(/d+)(?:/.(/d+))?.*Safari///.test(navigator.userAgent)) { if (/^data:/.test(url) { url = 'data:' + url.replace(/^data:([/w///-/+]+)/, defaultMime) } if (!window.open(url)) { location.href = url; } return } // 利用iframe來實現(xiàn)下載。需要注意的是,如果瀏覽器支持預(yù)覽該文件格式,則不能實現(xiàn)下載。 const f = document.createElement('iframe'); document.body.appendChild(f); f.src = url; setTimeout(() => { document.body.removeChild(f); }, 300)}// Case 1: 如果支持Blob和URLif (window.URL) { // 創(chuàng)建指向blob對象的URL const url = window.URL.createObjectURL(blob); saver(url); return;}// Case 2: 如果支持Blob和msSaveBlob,但不支持URL。if (navigator.msSaveBlob) { navigator.msSaveBlob(dataUrlToBlob(payload), filename); return;} // Case 3: 如果支持Blob,但不支持URL和msSaveBlob// 將blob轉(zhuǎn)成base64編碼的數(shù)據(jù)const reader = new FileReader()reader.readAsDataURL(blob)reader.onloadend = function () { const base64data = reader.result saver(base64data);}// Case 4: 如果Blob和URL都不支持if (!window.Blob && !window.URL) { const base64Data = window.btoa(blob); const url = `data:${mimeType};base64,${base64Data}`; saver(url);}
上面有個比較關(guān)鍵的函數(shù):dataUrlToBlob。它主要是將dataUrl轉(zhuǎn)成Blob對象,保證msSaveBlob接收的參數(shù)是Blob對象實例。function dataUrlToBlob (strUrl) { const parts = strUrl.split(/[:;,]/) const type = parts[1] const indexDecoder = strUrl.indexOf('charset') > 0 ? 3 : 2 // 如果字符串是base64編碼,解碼方法使用atob;否則使用decodeURIComponent。 const decoder = parts[indexDecoder] == 'base64' ? atob : decodeURIComponent // 解碼 const binData = decoder(parts.pop()) const mx = binData.length let i = 0 // 創(chuàng)建數(shù)組長度為mx的數(shù)組,其中數(shù)組元素都是0 const uiArr = new Uint8Array(mx) // 將解碼后的數(shù)據(jù)進行unicode編碼 for (i; i < mx; ++i) { uiArr[i] = binData.charCodeAt(i) } return new Blob([uiArr], { type })}
總結(jié)一下就是:先看是否支持Blob和URL,再看是否支持download屬性。wx.chooseImage({ count: 1, // 默認9 sizeType: ['original'], sourceType: ['album', 'camera'], success (res) { const localId = res.localIds[0] // 選擇圖片成功,上傳到微信圖片服務(wù)器 wx.uploadImage({ localId, // 需要上傳的圖片的本地ID,由chooseImage接口獲得 isShowProgressTips: 1, // 默認為1,顯示進度提示 success (res) { const serverId = res.serverId // 返回圖片的服務(wù)器端ID wx.downloadImage({ serverId, // 需要下載的圖片的服務(wù)器端ID,由uploadImage接口獲得 isShowProgressTips: 1, // 默認為1,顯示進度提示 success (res) { this.localId = res.localId } }) } }) }})
function longPress () { const target = document.getElementById('share-img') const startEvent = createTouchEvent(target, 'touchstart') target.dispatchEvent(startEvent) // 5s后觸發(fā)touchend setTimeout(() => { const endEvent = createTouchEvent(target, 'touchend') target.dispatchEvent(endEvent) }, 5000)}function createTouchEvent (touchTarget, type) { const event = document.createEvent('UIEvent') event.initUIEvent(type, true, true, window, 1) const touches = [{ target: touchTarget }] Object.defineProperties(event, { changedTouches: { value: touches } }) return event}
實踐下來,雖然能模擬長按事件,但無法喚起actionsheet。究其原因,應(yīng)該是原生微信app頂層layer對用戶的長按手勢有監(jiān)聽。所以無論js里怎么模擬長按事件,永遠不是用戶的手勢操作,也無法觸發(fā)長按手勢回調(diào),喚起actionsheet。NSString *imgURL = [NSString stringWithFormat:@"document.elementFromPoint(%f, %f).src", touchPoint.x, touchPoint.y];NSString *urlToSave = [self.webView stringByEvaluatingJavaScriptFromString:imgURL];UILongPressGestureRecognizer* longPressed = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressed:)];longPressed.delegate = self;[self.webView addGestureRecognizer:longPressed];
但微信H5里長按保存圖片,不止是頂層layer長按gensture的監(jiān)聽,也涉及到app與webview的通信。比如,app里可能會inject這段腳本到webview里進行長按事件的監(jiān)聽。let startTime = 0;document.addEventListner('touchstart', function() { startTime = Date.now();}, true)document.addEventListener('touchend', function() { const endTime = Date.now(); if (endTime - startTime > 3000) { // dispatchLongTimeEvent(); }}, true)
終上,我無法解決如何在微信H5里點擊保存圖片。關(guān)鍵詞:圖片,保存
微信公眾號
版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。