24 年了,问题依旧存在,没人管吗?
IOS下小程序 webview 内嵌H5页面,使用input file拍照确认后页面会刷新IOS下,小程序 webview 内嵌H5页面,使用input file拍照确认后页面会刷新 , 并且获取不到刚才拍摄的照片,请问这是怎么回事? <template> <div class="wrapper"> <div class="picture"> <scroller lock-y scrollbar-x> <div class="scroll-wrapper" :style="{width:( imgList.length * 75 )+'px'}"> <div class="cuspic" v-for="(item,index) of imgList" :key="index"> <img :src="item" @click="show(index)"/> <!-- <span @click="del(index)" class="badge"> <span class="del-icon"></span> </span>--> <span class="del-icon" @click="del(index)" ></span> </div> </div> </scroller> <div class="up-wrapper"> <div class="file-icon" v-show="imgList.length<max"> <img @click="clickFile" src="../../../common/assets/icon/apply/Group 70@3x.png"/> <input ref="fileinput" type="file" accept="image/*" capture="camera" fieldName="file" multiple="multiple" @change="selectFiles" class="fileinput" /> </div> <div class="pic-hint"> <div class="max-message">上传检查报告或患处照片(最多9张)</div> <div class="g-pic">照片仅自己和医生可见</div> </div> </div> </div> <div> <loading :show="loadingShow" text="上传中"></loading> </div> <!--------图片预览-------start--> <div v-transfer-dom> <previewer :list="previewList" ref="previewer" :options="options"> <template slot="button-before"> </template> </previewer> </div> <!-------图片预览-------end--> </div> </template> <script type="text/ecmascript-6"> import {Badge, Loading, TransferDomDirective as TransferDom, Previewer,Grid, GridItem,Scroller } from 'vux' import {uploadFile} from '@network/Api' import {mapState,mapMutations} from 'vuex' export default { name: 'imageUpload', directives: { TransferDom }, components: { Badge, Loading, Previewer,Grid, GridItem,Scroller }, props: { multiple: { type: Boolean, default: true, }, value: { type: [Boolean, String, Number, Array], default: false }, max: { type: [Boolean, String, Number, Array], default: 9 } }, data() { return { files: null, imgList: [], imgListBig: [], formData: null, fileUrl: [], loadingShow: false, options: { getThumbBoundsFn(index) { // find thumbnail element let thumbnail = document.querySelectorAll('.cuspic')[index] // get window scroll Y let pageYScroll = window.pageYOffset || document.documentElement.scrollTop // optionally get horizontal scroll // get position of element relative to viewport let rect = thumbnail.getBoundingClientRect() // w = width return {x: rect.left, y: rect.top + pageYScroll, w: rect.width} // Good guide on how to get element coordinates: // http://javascript.info/tutorial/coordinates }, isClickableElement: function (el) { return /previewer-delete-icon/.test(el.className) }, tapToToggleControls: false, }, directives: { TransferDom }, } }, watch: { imgList(val) { this.$emit('input', val) }, bigPictureUrls(){ this.imgListBig = this.bigPictureUrls } }, computed:{ ...mapState({ bigPictureUrls: state => state.bigPictureUrls }), previewList(){ let array = []; this.imgListBig.map((item, index) => { array.push({ src: item }) }) console.log('array---缓存大图',array) return array } }, methods: { ...mapMutations(['saveBigPictureUrl']), //压缩图片 compressImage(src) { return new Promise(function (resolve, reject) { let _this = this, imgType let img = new Image() if (src) { imgType = src.split(';')[0] if (imgType) { imgType = imgType.split(':')[1] } } img.src = src img.onload = function () { //计算符合目标尺寸宽高值,若上传图片的宽高都大于目标图,对目标图等比压缩;如果有一边小于,对上传图片等比放大。 let goalWidth = 1080, //目标宽度 goalHeight = 1080, //目标高度 imgWidth = img.naturalWidth, //图片宽度 imgHeight = img.naturalHeight, //图片高度 tempWidth = imgWidth, //放大或缩小后的临时宽度 tempHeight = imgHeight, //放大或缩小后的临时宽度 r = imgWidth / imgHeight, //压缩比 quality = 0.5 //图片压缩质量 // 宽高均 <= 1080,图片尺寸大小保持不变 if (imgWidth < goalWidth && imgHeight < goalHeight) { } // 宽高均 > 1080 && 宽高比 > 2, else if (imgWidth > goalHeight && imgWidth > goalHeight) { // 宽大于高 取较小值(高)等于1080,较大值等比例压缩 if (r > 1) { tempHeight = goalHeight tempWidth = goalHeight * r } // 高大于宽 取较小值(宽)等于1080,较大值等比例压缩 (宽高比在0.5到2之间 ) else { tempHeight = goalWidth / r tempWidth = goalWidth } } // 宽或高 > 1080 else { // 宽图 图片尺寸大小保持不变 if (r > 2) { tempWidth = imgWidth tempHeight = imgHeight } // 长图 图片尺寸大小保持不变 else if (r < 0.5) { tempWidth = imgWidth tempHeight = imgHeight } // 宽大于高 取较大值(宽)等于1080,较小值等比例压缩 else if (r > 1) { tempWidth = goalWidth tempHeight = goalWidth / r } // 高大于宽 取较大值(高)等于1080,较小值等比例压缩 else { tempHeight = goalHeight tempWidth = goalHeight * r } } let canvas = document.createElement('canvas') let ctx = canvas.getContext('2d') canvas.width = tempWidth canvas.height = tempHeight ctx.drawImage(img, 0, 0, tempWidth, tempHeight) // let base64 = canvas.toDataURL(imgType || 'image/jpeg', quality) canvas.toBlob(function (blob) { resolve(blob) }, imgType || 'image/jpeg') } }) }, compressImageWithFiles(files) { let fileProms = []; for (let file of files) { let fp = new Promise((resolve, reject) => { let vueInst = this; let reader = new FileReader() reader.onload = function (e) { let pro = vueInst.compressImage(e.target.result); resolve(pro) } reader.readAsDataURL(file); }) fileProms.push(fp); } return Promise.all(fileProms) }, async selectFiles(e) { const maxCount = this.max const files = e.target.files if (!files.length) { return } console.log('------image size------',files[0].size) let count = this.imgList.length + files.length if (count > maxCount) { this.$alert.error({ content: `最多上传${maxCount}张`, confirmText: '好的', onConfirm() { } }) return } let filesFilter = await this.converImgList(files); if (filesFilter == null || filesFilter.length == 0) { return } filesFilter = await this.compressImageWithFiles(filesFilter); this.formData = new FormData() if (this.multiple) { for (let i = 0; i < filesFilter.length; i += 1) { this.formData.append('file', filesFilter[i]) } this.formData.append('userid', shareInst.store.state.user.uid) this.formData.append('ext', '80') this.formData.append('module', 1) } else { this.file = filesFilter[0] this.formData.append('userid', shareInst.store.state.user.uid) this.formData.append('file', this.file) this.formData.append('ext', '80') this.formData.append('module', 1) } this.upload() let ele = document.querySelector('.scroll-wrapper') if(this.imgList.length >=4){ console.log('this.imgList.length------ ',this.imgList.length ) ele.style.transform =`translate(${-90 * (this.imgList.length - 4) }px,0px)` } }, async converImgList(files) { let maxSize = '10MB'; let allowed = [".jpg", ".gif", ".png", ".jpeg"]; let _this = this; let errFile = [] for (let i = 0; i < files.length; i++) { let file = files[i] if (!this.checkType(file, allowed)) { errFile.push({ index: i, lable: file.name, type: 'type' }) continue } if (!this.limitFileSize(file, maxSize)) { errFile.push({ index: i, lable: file.name, type: 'size' }) continue } /* let reader = new FileReader(); reader.readAsDataURL(file); reader.onload = function (e) { _this.imgList.push(this.result) }*/ } if (errFile.length) { let sizeErr = '' let typeErr = '' let errIndex = [] errFile.map(item => { if (item.type == 'size') { sizeErr += item.lable + ' | ' } if (item.type == 'type') { typeErr += item.lable + '| ' } errIndex.push(item.index) }) let content = ''; if (sizeErr) { sizeErr = sizeErr.substring(0, sizeErr.length - 2) content += `单文件大小超出[${maxSize}]:${sizeErr}`; } if (typeErr) { sizeErr = typeErr.substring(0, typeErr.length - 2) content += `类型只允许[${allowed}]:${typeErr}`; } this.$alert.error({ content: `${content},请重新上传`, confirmText: '好的', onConfirm() { } }) this.$refs.fileinput.value = '' return null } return files; }, upload() { // this.loadingShow = true; uploadFile(this.formData).then((res) => { if (res && res.length) { res.map(item => { let str1 = this.insertStr(item.filepath, item.filepath.lastIndexOf('/'), '/thumb') let str2 = this.insertStr(str1, str1.lastIndexOf('_'), '_thumb') this.imgList.push(str2) console.log('str2---',str2) this.imgListBig.push(item.filepath) this.$store.commit('saveBigPictureUrl', this.imgListBig) console.log(' this.imgListBig-----', this.imgListBig) }) } // this.loadingShow = false; }).catch((e) => { }) this.$refs.fileinput.value = '' }, // DataURL转Blob对象 dataURLToBlob(dataurl) { var arr = dataurl.split(','); var mime = arr[0].match(/:(.*?);/)[1]; var bstr = atob(arr[1]); var n = bstr.length; var u8arr = new Uint8Array(n); while (n--) { u8arr[n] = bstr.charCodeAt(n); } return new Blob([u8arr], {type: mime}); }, clickFile() { this.$refs.fileinput.click() }, limitFileSize(file, limitSize) { var arr = ["KB", "MB", "GB"] var limit = limitSize.toUpperCase(); var limitNum = 0; for (var i = 0; i < arr.length; i++) { var leval = limit.indexOf(arr[i]); if (leval > -1) { limitNum = parseInt(limit.substr(0, leval)) * Math.pow(1024, (i + 1)) break } } if (file.size > limitNum) { return false } return true }, insertStr(soure, start, newStr) { return soure.slice(0, start) + newStr + soure.slice(start); }, checkType(file, allowed) { const fileName = file.name; const seat = fileName.lastIndexOf("."); const extension = fileName.substring(seat).toLowerCase(); return this.contains(allowed, extension) }, contains(arr, obj) { let i = arr.length; while (i--) { if (arr[i] == obj) { return true; } } return false; }, del(index) { this.imgList.splice(index, 1); this.imgListBig.splice(index, 1); }, show(index) { this.$refs.previewer.show(index) }, }, created() { this.imgList = this.value this.imgListBig = this.bigPictureUrls }, } </script> <style lang="scss" type="text/scss" scoped> .wrapper { width: 100%; overflow: hidden; .scroll-wrapper{ overflow: auto; } .picture { width: auto; .cuspic { display: inline-block; margin-right: 15px; margin-top: 10px; position: relative; .del-icon{ position: absolute; right: -8px; top: -8px; display: inline-block; width: 20px; height: 20px; background-size:100% 100%; background-position:center ; background-image: url("../../../common/assets/icon/apply/del@3x.png"); } } .file-icon { position: relative; display: inline-block; margin-right: 10px; input { position: absolute; left: 0; top: 24px; opacity: 0; } } img { width: 60px; height: 60px; /* margin-right: 9px;*/ margin-left: 0px; /* margin-top: 5px;*/ border-radius: 3px; object-fit:cover; } } /deep/ .weui-grids:before { height: 0px; border-top: none; } /deep/ .weui-grid:after { height: 0px; border-bottom: none; } .pic-hint{ height: 60px; display: inline-flex; justify-content: center; flex-direction: column; align-content: center; vertical-align: middle; } .g-pic{ color: $subtitle-color; } .max-message{ } .up-wrapper{ display: flex; justify-content: flex-start; align-content: center; margin-top: 10px; } /deep/ .weui-grid{ padding: 10px; } } </style>
04-15真的无语,官方除了让提供这个那个,还会说点别的吗?
webview内嵌H5,拍照上传图片闪退到H5首页input type=“file” 使用vant组件库直接掉起摄像头,iOS15.5或iOS15.6的iPhone 13均会闪退,必现,频率超高。 [图片] 使用微信SDK的wx.chooseImage上传,最初iOS用着还行不咋闪退频率蛮低,但最近不知道咋了又复现闪退,与上面同样的机型,闪退频率超高 [图片] 以上两种方法均是掉起摄像头,拍完照,点击“确定”或“使用照片”时,会闪退到webview内嵌的H5首页,用户体验非常非常非常不好 看了社区有很多其他人反馈这个问题,也尝试了其他人的解决方案,但仍不得其解 有说把webview页面的onshow代码放在onload里面的,尝试仍然闪退。 有说微信SDK使用1.2.0版本的,尝试仍然闪退。 有说运行内存不足清楚后台的,有用但不多,有时清了后台仍然会闪退。 现在是希望微信官方可以解决一下这个问题,或者给这个问题提供个替代方案,让咱们可以正常使用,先感谢为敬!!
03-19