这篇文章是一些零碎的知识点,可能会有点杂,有耐心的可以看下。
一、屏幕滑动事件
1、pc触屏事件和移动端触屏事件
pc上的web页面鼠标会产生onmousedown、onmouseup、onmouseout、onmouseover、onmousemove的事件,但是在移动终端如 iphone、ipod Touch、ipad上的web页面触屏时会产生ontouchstart、ontouchmove、ontouchend、ontouchcancel 事件,分别对应了触屏开始、拖拽及完成触屏事件和取消。
当按下手指时,触发ontouchstart;
当移动手指时,触发ontouchmove;
当移走手指时,触发ontouchend。
当一些更高级别的事件发生的时候(如电话接入或者弹出信息)会取消当前的touch操作,即触发ontouchcancel。一般会在ontouchcancel时暂停游戏、存档等操作。
2、Touch事件与Mouse事件的出发关系
在触屏操作后,手指提起的一刹那(即发生ontouchend后),系统会判断接收到事件的element的内容是否被改变,如果内容被改变,接下来的事件都不会触发,如果没有改变,会按照mousedown,mouseup,click的顺序触发事件。特别需要提到的是,只有再触发一个触屏事件时,才会触发上一个事件的mouseout事件。
3、移动端touch事件在pc端无法滑动,需要增加点击事件
next(){
this.moveTo(this.pageIndex++, true)
},
其实除了点击的方法,还可以用vue自定义指令v-scroll,但是由于滚动的元素高度是6710,而且没占位,没有溢出滚动,所以就滚动不了。
4、增加滚动条
给外层的元素增加滚动条,内层元素给固定和宽度,就可以增加X轴滚动条。
.dbta{
width 255px
height 420px
margin 20px auto
overflow-x:scroll
border: 1px solid #ddd;
position relative
.overflowy{
width 800px
flex-wrap: wrap;
}
}
完整的页面滚动代码见下方:
<template>
<div class="main" :class="{ other_bg: pageIndex > 0 }">
<div class="share-tip-box"></div>
<div
class="swiper-wrapper"
id="wideWrapper"
ref="swiperWrappers"
data-src="swiperWrappers111111111"
@touchstart="onSwiperTouchStart"
@touchmove="onSwiperTouchMove"
@touchend="onSwiperTouchEnd"
:class="{ anim: anim }">
<template>
<div class="page1" :class="{ active: 0 == pageIndex }" :style="{ height: height + 'px' }"></div>
<div class="page2" :class="{ active: 1 == pageIndex }" :style="{ height: height + 'px' }"></div>
<div class="page3" :class="{ active: 2 == pageIndex }" :style="{ height: height + 'px' }"></div>
<div class="page4" :class="{ active: 3 == pageIndex }" :style="{ height: height + 'px' }"></div>
<div class="page5" :class="{ active: 5 == pageIndex }" :data-src="pageIndex" :style="{ height: height + 'px' }"></div>
<div class="page6" :class="{ active: 8 == pageIndex }" :data-src="pageIndex" :style="{ height: height + 'px' }"></div>
<div class="page7" :class="{ active: 9 == pageIndex }" :data-src="pageIndex" :style="{ height: height + 'px' }"></div>
<div class="page8" :class="{ active: 10 == pageIndex }" :data-src="pageIndex" :style="{ height: height + 'px' }"></div>
<div class="page9" :class="{ active: 11 == pageIndex }" :data-src="pageIndex" :style="{ height: height + 'px' }"></div>
</template>
</div>
</div>
</template>
<script>
export default {
data() {
return {
isMobileBrowser: false,
mySwiperWraps: null, //swiper-wrapper resf实例
startY: 0, //touchstart时,手指y位置
pageIndex: 0, //当前页数 0开始
curIndex: 0,
pagesLength: 9, //总页数
height: 667, //整屏幕高度
anim: false,
der: 0.05,
activeIndex: "",
pageHeight:668,
}
},
methods: {
onSwiperTouchStart(e) {
this.startY = e.touches[0].clientY;
},
onSwiperTouchMove(e) {
let y = e.changedTouches[0].pageY - this.startY;
e.preventDefault()
if ((this.curIndex == 0 && y > 0) ||
(this.curIndex === this.pagesLength - 1 && y < 0)) {
y /= 2;
}
let dist = -this.curIndex * this.height + y;
this.mySwiperWraps.style.cssText +=
";-webkit-transform : translate3d(0px," + dist + "px" + ", 0px);" + "transform : translate3d(0px," + dist + "px" + ", 0px);";
this.anim = false;
},
onSwiperTouchEnd(e) {
let sub = (e.changedTouches[0].pageY - this.startY) / this.height;
let der = sub > this.der || sub < -this.der ? (sub > 0 ? -1 : 1) : 0;
this.moveTo(this.curIndex + der, true);
},
moveTo(index, flag) {
let cur = this.curIndex;
if (index < 0) {
index = 0;
}
if (index >= this.pagesLength) {
index = this.pagesLength - 1;
}
this.curIndex = index;
if (flag) {
this.anim = true;
} else {
this.anim = false;
}
this.mySwiperWraps.style.cssText +=
";-webkit-transform : translate3d(0px," + -index * this.height + "px" + ", 0px);" + "transform : translate3d(0px," + -index * this.height + "px" + ", 0px);";
if (index !== cur) {
this.pageIndex = index;
}
},
update() {
this.height = document.querySelector(".main").offsetHeight;
this.moveTo(this.curIndex < 0 ? 0 : this.curIndex, false);
},
format(percentage) {
return percentage === 100 ? '满级' : `${percentage}`;
}
},
mounted() {
this.userId = this.$route.params.userId
this.fetchData()
this.fetchDbs()
this.mySwiperWraps = this.$refs.swiperWrappers;
this.update();
this.isMobileBrowser = isMobile()
window.addEventListener(
"resize",
() => {
console.log("resize");
this.update();
},
false
);
}
};
</script>
<style lang='stylus' scoped>
.share-tip-box {
position fixed
z-index 1000
width 100%
height 100%
top 0
left 0
background url("") right top / no-repeat
}
.main{
max-width 375px
max-height 668px
margin auto
}
.main {
position: fixed;
top: 0px;
left: 0;
right: 0;
bottom: 0;
overflow: hidden;
-webkit-background-size: 100% 100%;
background-size: 100% 100%;
-webkit-overflow-scrolling: touch;
}
.swiper-wrapper{
min-height: calc(100% + 1px)
}
.anim {
-webkit-transition: all 500ms ease-out 0s;
transition: all 500ms ease-out 0s;
}
.other_bg {
background-size: 100% 100%;
}
}
二、微信分享
验签规则
分享链接时,由于需要在原本的链接后增加一个/id,方便查看其他用户的数据,所以最开始是想在分享链接后拼接上一个/id,发现分享出来的链接,没有带上id。
微信验签:
1)微信要把信息推送给开发者服务器,那么开发者应该告诉微信,当有新的请求时,应该调用的地址,即在基本配置的下方填写相关信息。
服务器地址(URL):微信收到用户的操作时,会对该地址发送一次请求,并附带用户的操作行为相关的信息。
注:服务器地址填写时,http请求,默认端口为80,https端口为443,一般来讲,这个地方,我们是填写域名,然后进行转发,但是域名需要备案等等一些操作,比较麻烦,我这里使用的是nginx将80端口的请求转发到8080(项目使用的端口)。
具体的nginx.conf(nginx.xxx/conf下面)的配置如下:
令牌(Token):weixin
消息加解密密钥:为方便测试,可以选择使用明文模式,尤其是在开发阶段,会更加方便查找问题。
(2)微信验签,会在启动服务器配置时,向配置的url发送一次请求,我们需要提取request中的signature、timestamp、nonce、echostr,并创建token(weixin)。
验签步骤:
①获取出上述四个必要的数据,若存在一个为空,则该请求不做处理。
②将signature、timestamp、nonce组成一个字符数组、并排序
③将排序后的数组组成一个字符串,并进行SHA-1加密,将加密后的字符串与signature进行对比,若二者一致,则验签通过,返回echostr,若不一致,则不做处理,若验签失败,则微信配置也会提示失败。具体SHA-1加密代码如下:
若验签不通过,则需要核查失败的原因,请注意以下几点:
(1)开发者服务器是否收到请求
(2)定义的token是否一致
(3)在服务器上打印出接收到的参数,并核对,是否和前端一致
(4)SHA-1加密算法是否使用错误
若成功后,后续的开发就方便很多,能直观地看到微信传来的数据,这样方便代码的调试和修改。
if (isWinxin()) this.initShare()
initShare () {
let _user = this.userCencus
let _obj = {
iosUrl: this.getWechatSignUrl,
title: '2020墨天轮个人年度报告',
img: _user.headImgUrl,
desc: _user.account
}
initWxShare(_obj)
}
getWechatSignUrl (state) {
return state.wechatSignUrl
}
// 判断是否微信浏览器
export const isWinxin = () => {
let ua = navigator.userAgent.toLowerCase()
return ua.indexOf('micromessenger') !== -1
}
// 微信分享
export function initWxShare (obj) {
let pageUrl = isIos() ? obj.iosUrl.split('#')[0] :
window.location.href.split('#')[0]
getWxShareStatusApi({ url: pageUrl }).then(res => {
if (res.status === 200) {
let options = res.data
options.title = obj.title
options.img = obj.img
options.desc = obj.desc
wxShare.shareToWechat(options)
}
})
}