需求:移动端h5套壳应用,在启动app与进入h5页面之间有几秒白屏时间,需在此处添加loading动画。
出现白屏,是因为打包后 JS 和 CSS 文件比较大,还未加载完成,但index.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
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
<style>
#loading-mask {
position: fixed;
left: 0;
top: 0;
height: 100%;
width: 100%;
background: #fff;
user-select: none;
z-index: 9999;
overflow: hidden
}
.loading-wrapper {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -100%);
text-align: center;
}
.loading-dot {
animation: antRotate 1.2s infinite linear;
transform: rotate(45deg);
position: relative;
display: inline-block;
font-size: 64px;
width: 45px;
height: 45px;
box-sizing: border-box
}
.loading-dot i {
width: 22px;
height: 22px;
position: absolute;
display: block;
background-color: #EF621D;
border-radius: 100%;
transform: scale(.75);
transform-origin: 50% 50%;
opacity: .3;
animation: antSpinMove 1s infinite linear alternate
}
.loading-dot i:nth-child(1) {
top: 0;
left: 0
}
.loading-dot i:nth-child(2) {
top: 0;
right: 0;
-webkit-animation-delay: .4s;
animation-delay: .4s
}
.loading-dot i:nth-child(3) {
right: 0;
bottom: 0;
-webkit-animation-delay: .8s;
animation-delay: .8s
}
.loading-dot i:nth-child(4) {
bottom: 0;
left: 0;
-webkit-animation-delay: 1.2s;
animation-delay: 1.2s
}
.loading-text{
color: #EF621D;
font-size: 16px;
width: 150px;
margin-top: 23px;
}
@keyframes antRotate {
to {
-webkit-transform: rotate(405deg);
transform: rotate(405deg)
}
}
@-webkit-keyframes antRotate {
to {
-webkit-transform: rotate(405deg);
transform: rotate(405deg)
}
}
@keyframes antSpinMove {
to {
opacity: 1
}
}
@-webkit-keyframes antSpinMove {
to {
opacity: 1
}
}
</style>
<body>
<div id="app">
<div id="loading-mask">
<div class="loading-wrapper">
<span class="loading-dot loading-dot-spin"><i></i><i></i><i></i><i></i></span>
<div class="loading-text">正在加载</div>
</div>
</div>
</div>
</body>
|
在#app里添加loading元素,当Vue实例挂载到<div id="app">
元素上时,Vue会将该元素作为根节点,并用Vue组件中的模板内容替换掉原来的内容。
这样做在web端和安卓端都没有问题。但ios依然白屏,没有loading动画,如果把最外层的div#app元素去掉,ios可以显示加载动画(当然这样加载动画会一直显示),说明并非用到的css在ios不兼容。可能的原因是,iOS设备上的特殊渲染优化可能会导致在Vue实例挂载之前,被Vue挂载的DOM元素内部的原有内容被移除或隐藏。
解决办法是把loading元素挪到最外层,与div#app同级,在vue实例初始化完成后利用mounted钩子函数移除loading元素。
最终方案:
1
2
3
4
5
6
7
8
9
|
<!-- public/index.html -->
<style>略</style>
<div id="loading-mask">
<div class="loading-wrapper">
<span class="loading-dot loading-dot-spin"><i></i><i></i><i></i><i></i></span>
<div class="loading-text">正在加载</div>
</div>
</div>
<div id="app"></div>
|
1
2
3
4
5
6
7
8
9
10
|
// main.js
new Vue({
router,
store,
mounted(){
// 在Vue实例初始化完成后移除loading元素
const loadingElement = document.querySelector('#loading-mask');
document.body.removeChild(loadingElement);
}
}).$mount("#app");
|