晚上app上线,下午五点多产品临时提出需求,须要把一个H5页面的二维码图片保存到手机相册!这个二维码是公众号二维码,保存到相册的目的是让用户在微信中可以识别二维码从而关注公众号!css
拿到此需求,只有不到3个小时的开发时间,没时间去扯皮也没时间想太多,干就完了!html
H5图片保存,通常是长按保存,因此,首先要实现一个长按功能。前端
移动端使用touchstart
和touchend
来作长按功能,prevent
阻止浏览器默认行为,浏览器不少事件有默认行为,不阻止默认行为的话,浏览器会执行它的默认行为,咱们用 JavaScript 处理一个事件,一般不须要浏览器动做,因此阻止掉!prevent
是vue中的修饰符,关于修饰符的更多内容,能够去这里看事件修饰符。vue
htmlandroid
<img class="code" src="@/images/cloudStallUp/xyhd_05@3x.png" @touchstart.prevent="touchin" @touchend.prevent="cleartime" />
复制代码
jsios
touchin() {
clearInterval(this.Loop); //再次清空定时器,防止重复注册定时器
this.Loop = setTimeout(() => {
// 这里长按后执行的操做
}, 1000);
},
// 这个方法主要是用来将每次手指移出以后将计时器清零
cleartime() {
clearInterval(this.Loop);
},
复制代码
UI框架基本都有自带的dialog弹窗,若是你的项目使用了某个UI框架,直接使用它的就行。若是你的项目没有使用UI框架,那么就颇有必要本身实现一个dialog弹窗git
tips:不是全部项目都须要使用UI框架,若是项目很是简单,就不须要,原谅我这轮子党,喜欢本身造轮子,哪怕很差用!github
使用H5的dialog
标签写弹窗。web
htmlnpm
<dialog ref="dialog">
<div @click="saveImage">保存图片</div>
<div @click="closeDialog">取消</div>
</dialog>
复制代码
css
@function vw($px) {
@return ($px / 750) * 100vw;
}
$c_dd: #dddddd;
dialog {
border: none;
padding: 0;
div {
width: vw(750);
font-size: vw(30);
height: vw(80);
line-height: vw(80);
&:last-child {
border-top: 1px solid $c_dd;
}
}
}
/* 设置背景色 */
dialog::backdrop {
background: rgba(0, 0, 0, 0.6);
}
复制代码
js
touchin() {
clearInterval(this.Loop); //再次清空定时器,防止重复注册定时器
this.Loop = setTimeout(() => {
// 显示
this.$refs.dialog.showModal();
}, 1000);
},
......
复制代码
效果展现:
dialog
标签的兼容性颇有些问题
so,咱们须要一个polyfill
安装
npm install dialog-polyfill
复制代码
在页面中引入
import dialogPolyfill from 'dialog-polyfill'
复制代码
新建一个dialog-polyfill.scss
dialog {
position: absolute;
left: 0; right: 0;
width: -moz-fit-content;
width: -webkit-fit-content;
width: fit-content;
height: -moz-fit-content;
height: -webkit-fit-content;
height: fit-content;
margin: auto;
border: solid;
padding: 1em;
background: white;
color: black;
display: block;
}
dialog:not([open]) {
display: none;
}
dialog + .backdrop {
position: fixed;
top: 0; right: 0; bottom: 0; left: 0;
background: rgba(0,0,0,0.1);
}
._dialog_overlay {
position: fixed;
top: 0; right: 0; bottom: 0; left: 0;
}
dialog.fixed {
position: fixed;
top: 50%;
transform: translate(0, -50%);
}
复制代码
在页面中引入
@import "@/style/dialog-polyfill.scss";
复制代码
设置了polyfill 后,背景的css和原生的有所区别
/* 支持dialog */
dialog::backdrop {
background-color: green;
}
/* polyfill */
dialog + .backdrop {
background-color: green;
}
复制代码
使用polyfill
js
data() {
return {
dialog: null
};
},
mounted() {
this.dialog = this.$refs.dialog;
dialogPolyfill.registerDialog(this.dialog);
},
methods: {
touchin() {
clearInterval(this.Loop); //再次清空定时器,防止重复注册定时器
this.Loop = setTimeout(() => {
this.dialog.showModal();
}, 1000);
},
......
}
复制代码
// 首先考虑使用a标签下载
saveImage(url) {
if (!url) {
return new Error("图片地址不正确");
}
let a = document.createElement("a");
a.href = url;
a.download = "xxxxx";
if (document.all) {
a.click();
} else {
// 兼容 Firfox
var evt = document.createEvent("MouseEvents");
evt.initEvent("click", true, true);
a.dispatchEvent(evt);
}
this.closeDialog();
},
closeDialog() {
this.dialog.close();
},
复制代码
自测发如今pc有用,可是在手机端无用,此方案放弃
saveImage() {
if (!window.plus) return;
/* eslint-disable */
plus.gallery.save(
this.codeImg,
() => {
plus.nativeUI.alert("保存图片到相册成功");
},
() => {
plus.nativeUI.alert("保存失败");
}
);
/* eslint-enable */
this.closeDialog();
},
......
复制代码
写完后悲催的发现,咱们最开始架构设计的时候没有使用这个,无奈下也放弃了。关于更多的相关内容能够去这里了解5+ App开发入门指南
在mixin.js中封装
// 调用app方法
// androidName->安卓方法名
// iosName->ios方法名
// androidData->传给安卓的参数
// iosData->传给ios的参数
// h5Fuc->不属于安卓和ios时调用的函数
callAPPFunction(androidName, iosName, androidData, iosData, h5Fuc) {
switch (true) {
case this.UTILS.isAndroid:
window.hitumedia_android_js[androidName](androidData);
break;
case this.UTILS.isIOS:
window.webkit.messageHandlers[iosName].postMessage(iosData);
break;
default:
h5Fuc;
}
},
复制代码
在main.js中使用
// 导入全局混入
import Mixin from "@/utils/mixin.js";
Vue.mixin(Mixin);
复制代码
在页面使用
data() {
return {
codeImg: require("@/images/cloudStallUp/xyhd_05@3x.png")
};
},
...
saveImage() {
const url = location.href.split("/")[2];
// 获取到图片地址,架构缘由,咱们没有图片服务器,因此暂时只能使用使用项目的地址了
const postUrl = `http://${url}/activity/${this.codeImg}`;
this.callAPPFunction("onDownImgs", "", postUrl, "");
this.closeDialog();
},
...
复制代码
OK,完美实现需求。
写完此功能,自测经过后,提交产品验收,而后!!!产品说:“貌似app中不多看见保存二维码的吧,这个功能不要了~~~”
此功能不要了~~~~~~~~~~~~~~~
从这个实际的例子,得出总结,前端如何解决需求问题: