监听元素进入视口的函数

Element.getBoundingClientRect() 方法返回元素的大小及其相对于视口的位置。
getBoundingClientRect
通过这个方法可以判断元素是否在视口中,如果元素在视口中的话就执行函数

1
2
3
4
5
6
7
8
9
10
11
12
// 检查元素是否在视口内
isElementVisible(el, animationFn) {
const rect = el.getBoundingClientRect()
const vWidth = window.innerWidth || document.documentElement.clientWidth
const vHeight = window.innerHeight || document.documentElement.clientHeight

if(rect.right < 0 || rect.bottom < 0 || rect.left > vWidth || rect.top > vHeight) {
return false
} else {
animationFn(el)
}
}

关于(rect.right < 0 || rect.bottom < 0 || rect.left > vWidth || rect.top > vHeight)判断的解释

css transition

html 结构

1
2
3
<p class="brief-text slide-tran slide-bottom">
牛津大学成立的确切日期尚不清楚,但该校的历史至少可以追溯到1096年。牛津大学位于伦敦西北约60英里处,该校大约45%的学生是研究生。一半以上的研究生把研究作为他们学习的一部分。牛津大学的研究在其所有四个学术部门进行:人文学科;数学、物理和生命科学;医学科学和社会科学。牛津大学的校历分为三个学期——米迦勒节(秋季)、希拉里节(春季)和三一节(夏季)——每个学期八周。大学的教学语言是英语。牛津大学包括一所中央大学,38所学院,还有六个永久性私人礼堂,它们的规模通常比大学还小,开设的科目更少。
</p>

css 类名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/* 先写一个类名,标记这个元素需要过渡动画 */
.slide-tran {
transition: all 0.6s;
}
/* 从下方淡入的元素的初始状态 */
.slide-bottom {
transform: translateY(100px);
opacity: 0;
}

.slide-top-in {
opacity: 1;
transform: translateY(0);
}
/* 从左侧淡入的元素的初始状态 */
.slide-left {
transform: translateX(-100px);
opacity: 0;
}

.slide-right-in {
opacity: 1;
transform: translateX(0);
}

页面滚动到元素的位置时,修改元素 class

1
2
3
4
5
6
7
8
9
10
slideFromBottom(el) {
if(el.classList.contains('slide-top-in')) return
el.classList.remove('slide-bottom')
el.classList.add('slide-top-in')
}
slideFromLeft(el) {
if(el.classList.contains('slide-right-in')) return
el.classList.remove('slide-left')
el.classList.add('slide-right-in')
}

完整的 JavaScript 代码

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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
window.onload = () => {
class PageSlideIn {
constructor() {
this.initPage();
this.bindDocScroll();
}
// 页面加载后,视口内元素浮现
initPage() {
var that = this;
var slideElements = document.querySelectorAll(".slide-tran");
slideElements.forEach((el) => {
if (el.classList.contains("slide-bottom")) {
that.isElementVisible(el, that.slideFromBottom);
} else if (el.classList.contains("slide-left")) {
that.isElementVisible(el, that.slideFromLeft);
}
});
}
// 页面滚动事件
bindDocScroll() {
var that = this;
window.addEventListener("scroll", function () {
that.isElementVisible(
document.querySelector(".brief-text"),
that.slideFromBottom
);
that.isElementVisible(
document.querySelector(".brief-imgbox"),
that.slideFromLeft
);
that.isElementVisible(
document.querySelector(".advabox"),
that.slideFromBottom
);
that.isElementVisible(
document.querySelector(".prodbox"),
that.slideFromLeft
);
that.isElementVisible(
document.querySelector(".table"),
that.slideFromBottom
);
});
}
// 检查元素是否在视口内
isElementVisible(el, animationFn) {
const rect = el.getBoundingClientRect();
const vWidth = window.innerWidth || document.documentElement.clientWidth;
const vHeight =
window.innerHeight || document.documentElement.clientHeight;

if (
rect.right < 0 ||
rect.bottom < 0 ||
rect.left > vWidth ||
rect.top > vHeight
) {
return false;
} else {
animationFn(el);
}
}
// slideFromBottom动画
slideFromBottom(el) {
if (el.classList.contains("slide-top-in")) return;
el.classList.remove("slide-bottom");
el.classList.add("slide-top-in");
}
slideFromLeft(el) {
if (el.classList.contains("slide-right-in")) return;
el.classList.remove("slide-left");
el.classList.add("slide-right-in");
}
}
new PageSlideIn();
};

Codepen