今天看到一个响应式的页面,看完才感觉原来最开始学html
的时候,我就会做响应式页面了。后面因为CSS+DIV
网页布局的出现,才使得元素被束缚。。。
感觉收获最大的就是,知道了媒体查询和rem的使用方向上面的不同:
- 媒体查询:针对页面为了适应不同设备,说白了就是为了让页面在不同的设备(pc端,移动端,平板)上显示的有美感。
- rem :更多是针对移动端布局,只要是为了实现让页面在所有的移动端设备上看起来都是一样.
好了,话题回到fullpage.js的实现过程中来。
前端时间看到很多pc段页面都是用这个插件。今天再github
上面看了看用法,开始用自己思路想了一个小时,后面看了看源码。这里总结下fullpage.js的实现思路;
fullpage.js
大致思路。
最开始,不用说当然是一个html,然后给加上样式1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
*{margin:0; padding:0;}
*{box-sizing: border-box;}
*{margin:0; padding:0;}
*{box-sizing: border-box;}
html,body,section{
width:100%;
height:100%;
}
body{
overflow:hidden;
}
section>div{
height:100%;
text-align: center;
}
.box:nth-of-type(1){
background:yellow;
}
.box:nth-of-type(2){
background:green;
}
.box:nth-of-type(3){
background:red;
}
.box:nth-of-type(4){
background:pink;
}
</style>
</head>
<body>
<section>
<div class="box">page1</div>
<div class="box">page2</div>
<div class="box">page3</div>
<div class="box">page4</div>
</section>
</body>
</html>
这里为了好区分,我给每一个div都加上不同的颜色。
然后我们就会得到这样一幅图
如何滑动
得到这样一个图还是不行啊,到底如何让他根据我的动作动起来呢??我这里想到了JS
获取滑动的距离
- 因为每次要滑动的距离 都是一个窗口的大小,所以很简单 这里要做的就是先确定 滑动的距离
1
var fullHeight=document.documentElement.clientHeight;
获取滑动的方向
- 知道了滑动距离之后,我还需要知道他到底是向上滑还是向下滑动啊,这样我也好作出与之相对应的操作对应。
对此我当时的想法是,我能不能先一开始记录下我所对应的窗口window
的scolltop
值的大小,然后和我操作后的值比大小,从而判断我是想上滑动的还是向下滑动的。1
2
3
4
5
6
7
8
9
10oldScrolltop=$(window).scrollTop();
$(window).on("scroll",function(){
var newScrolrrtop=$(window).scrollTop();
var result=newScrolrrtop-oldScrolltop;
if(result>0){
console.log("我在向下滑动。");
}else{
console.log("我在向上滑动")
}
})
然而结果却是,不管我上滑还是下滑,都是console.log(“我在向上滑动”),这里肯定哪里出错了。
后面排查的时候发现。这里有个严重的错误:
- 我最开始就定义了
oldScroll
相当于我每次都是用最新的窗口滚动距离,减去初始的那个窗口滚动距离,很明显这一开始就错了。
后面发现 应该这样弄1
2
3
4
5
6
7
8
9
10
11oldScrolltop=$(window).scrollTop();
$(window).on("scroll",function(){
var newScrolltop=$(window).scrollTop();
var result=newScrolltop-oldScrolltop;
oldScrolltop=newScrolltop;
if(result>0){
console.log("我在向下滑动。");
}else{
console.log("我在向上滑动")
}
})
这样就相当于:
- 我下一次的”旧数据”是我前一次的”新数据”
- 虽然有点绕,但是我相信大家可以忽略我第一句话,直接看代码就能明白。。。。
这样就能确保我每次滑动鼠标,都会给我反馈一个正确的滑动方向。
获取方向之后的行动
当获取到了。每次滑动时的方向之后,我们要做什么?————当然是 让这个”玩意”上下动起来啊。难道还在控制台看我向上滚了,向下滚了。。。
要使得屏幕上下滚动,第一时间想到的就是$(window).srollTop()
,当我们知道每次鼠标滑动的方向
和元素内部的高度
这样就很好做了:
- 如果鼠标是向上滚动,那么我们就直接让窗口的距离向下滚动一个
fullHeight
的距离; - 如果鼠标是向下滚动,那么我们就直接让窗口的距离向上滚动一个
fullHeight
的距离;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29这里我们把上面的代码封装成一个函数。
var fullHeight=document.documentElement.clientHeight,
oldScrolltop=$(window).scrollTop(),
key;
$(window).on("scroll",function(){
if(key)return;
key=true;
var response= getScrolltop();
if(response==="down"){
$(window).scrollTop($(window).scrollTop()+fullHeight);
key=false;
}else{
$(window).scrollTop($(window).scrollTop()-fullHeight);
key=false;
}
})
function getScrolltop(){
var newScrolltop=$(window).scrollTop(),
result=newScrolltop-oldScrolltop;
oldScrolltop=newScrolltop;
if(result>0){
return "down";
}else{
return "up";
}
}
然后试着 试了试,却发现了问题。
再滑动的时候,视窗类的元素会从第一个直接滑到最后一个。很明显这不是我们想要的样子。
另一种尝试,wheel
事件。
这里我们把监听事件的类型从,监听滚动事件scroll
改成wheel
监听鼠标的滚轮事件.1
2
3$(window).on("wheel",function(){
console.log("我滑动了。")
})
但是这样有一个问题:
因为我之前判断滚动方向是通过比较前后$(window).scrollTop
值的大小来判断的,这里其实可以通过另外一个值来直接判断。省去比较前后$("window").scrollTop
值的比较,1
2
3$(window).on("wheel",function(e){
console.log(e)
})
当鼠标滑轮向下滚动时:
当鼠标滑轮向上滚动时:
这样一来我们就只需要通过判断e.originalEvent.deltaY
这个值的大小,从而就能知道鼠标是向上滚动还是向下滚动了。
整理之后 我们代码就变成这样了:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17var fullHeight=document.documentElement.clientHeight,
oldScrolltop=$(window).scrollTop(),
key;
$(window).on("wheel",function(e){
if(key)return;
key=true;
var response= e.originalEvent.deltaY;
if(response>0){
$(window).scrollTop($(window).scrollTop()+fullHeight);
key=false;
}else{
$(window).scrollTop($(window).scrollTop()-fullHeight);
key=false;
}
})
但是这样 功能也算大致实现了。有点小问题,当鼠标滑动过快的时候,我们发现屏幕会一下子从page1
到page2
这里用animate
稍微改进下。1
2
3
4
5
6
7
8
9
10
11
12
13var fullHeight=document.documentElement.clientHeight,
oldScrolltop=$(window).scrollTop(),
key;
$(window).on("wheel",function(e){
if(key)return;
key=true;
var response= e.originalEvent.deltaY;
var dection =response>0?"+=":"-=";
$("body").animate({"scrollTop":dection+fullHeight},1000,function(){
key=false;
})
})
到此为止.fullpage.js的大致功能就已经实现了。
不过既然是自己动手造轮子,就弄点稍微好一点。这里其实还可以在做一点加工,让他适应手机端和PC端。
让fullpage.js使用手机端
我们知道手机端屏幕和PC端屏幕。最大的不同就是:
- 手机端没有鼠标啊。你让我怎么用
wheel
事件. - 不过手机端上多了一个
touch
事件
这样问题就很好解决了。我们同时监听这两个事件,不就是相当于完成了移动端和PC端的自适应??
在移动端中,因为有了touch
事件,如果要监控判断用户在移动端是向上滑动,还是向下滑动(这里简单起见,不考像左右滑动ongoing的,当然判断左右滑动和上下滑动类似);而且在移动端中我更倾向于使用css3来代替animate;
好了不多说,我们直接上代码1
2
3
4
5
6
7
8
9
10
11
12
13
14
15$("body").on("touchstart", function(e) {
e.preventDefault();
startY = e.originalEvent.changedTouches[0].pageY;
});
$("body").on("touchend", function(e) {
e.preventDefault();
moveEndY = e.originalEvent.changedTouches[0].pageY;
Y = moveEndY - startY;
if(Y>0) {
console.log("向下滑");
}else{
console.log("向上滑");
}
});
这样我就直接可以在`touch`事件开始之前,记录一个值,然后在`touch`事件结束的时候,再记录一个值。
然后比较两者之间的大小,当大于某个值的时候,作出相对应的动作(当然这个值的大小我们可以规定)