晚上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中不多看見保存二維碼的吧,這個功能不要了~~~」
此功能不要了~~~~~~~~~~~~~~~
從這個實際的例子,得出總結,前端如何解決需求問題: