滚动时滑动门效果无法实现
来源:5-5 JS实现滑动门效果
MiMicccc
2020-11-19 21:21:54
# 具体遇到的问题
滑动门点击时效果可以有,但是在滚动页面时,导航条滑动效果无法显示
# 报错信息的截图
# 相关课程内容截图
回顾视频时发现我少打了代码
少打得代码为注释的代码,但是加上的话会报错
# 粘贴全部相关代码,切记添加代码注释(请勿截图)
/*
1.页面载入完成后所有的动画元素设置_animate_init
2.页面滚动到某一屏 开始播放动画/导航条,大纲出现
3.导航条,大纲联动(双向定位-滚动导航条定位/大纲定位)
4.导航条滑动门特效
*/
// 1
// 获取元素
var getElem = function (selector) {
return document.querySelector(selector);
}
var getAllElem = function (selector) {
return document.querySelectorAll(selector);
}
// 获取元素的样式
var getCls = function (element) {
return element.getAttribute('class');
}
// 设置元素的样式
var setCls = function (element, cls) {
return element.setAttribute('class', cls)
}
// 为元素添加样式
var addCls = function (element, cls) {
var baseCls = getCls(element);
if (baseCls.indexOf(cls) === -1) {
setCls(element, baseCls + " " + cls)
}
return;
}
// 为元素删除样式
var delCls = function (element, cls) {
var baseCls = getCls(element);
if (baseCls.indexOf(cls) != -1) {
setCls(element, baseCls.split(cls).join(' ').replace(/\s+/g, ' '));
}
return;
}
// 1.初始化样式init
var screenAnimateElements = {
'.screen-1': [
'.screen-1__heading',
'.screen-1__phone',
'.screen-1__shadow'
],
'.screen-2': [
'.screen-2__heading',
'.screen-2__subheading',
'.screen-2__phone',
'.screen-2__point_i_1',
'.screen-2__point_i_2',
'.screen-2__point_i_3',
],
'.screen-3': [
'.screen-3__heading',
'.screen-3__phone',
'.screen-3__subheading',
'.screen-3__features',
],
'.screen-4': [
'.screen-4__heading',
'.screen-4__subheading',
'.screen-4__type__item_i_1',
'.screen-4__type__item_i_2',
'.screen-4__type__item_i_3',
'.screen-4__type__item_i_4',
],
'.screen-5': [
'.screen-5__heading',
'.screen-5__subheading',
'.screen-5__bg',
]
}
function setScreenAnimateInit(screenCls) {
var animateElements = screenAnimateElements[screenCls];// 获取需要设置动画的元素
for (var i = 0; i < animateElements.length; i++) {
var element = document.querySelector(animateElements[i]);
var baseCls = element.getAttribute('class');
// console.log(baseCls);
element.setAttribute('class', baseCls + ' ' + animateElements[i].substr(1) + '_animate_init');
}
}
window.onload = function () {
// 为所有元素设置init
for (k in screenAnimateElements) {
// 优化让第一屏默认自动播放
if (k === '.screen-1') {
continue;
}
setScreenAnimateInit(k);
}
console.log('load');
}
// 2.滚动到哪就播放到哪
// 滚动条设置
function playScreenAnimateDone(screenCls) {
var animateElements = screenAnimateElements[screenCls];// 获取需要设置动画的元素
for (var i = 0; i < animateElements.length; i++) {
var element = document.querySelector(animateElements[i]);
var baseCls = element.getAttribute('class');
element.setAttribute('class', baseCls.replace('_animate_init', '_animate_done'));
}
}
window.onscroll = function () {
var top = document.documentElement.scrollTop || document.body.scrollTop;
if (top > 100) {
addCls(getElem('.header'), 'header_status_back');
playScreenAnimateDone('.screen-1');
} else {
delCls(getElem('.header'), 'header_status_back');
switchNavItemsActive(0);
}
if (top > 400) {
addCls(getElem('.outline'), 'outline_status_in');
}
if (top > (800 * 1 - 100)) {
playScreenAnimateDone('.screen-2');
switchNavItemsActive(1)
}
if (top > (800 * 2 - 100)) {
playScreenAnimateDone('.screen-3');
switchNavItemsActive(2)
}
if (top > (800 * 3 - 100)) {
playScreenAnimateDone('.screen-4');
switchNavItemsActive(3)
}
if (top > (800 * 4 - 100)) {
playScreenAnimateDone('.screen-5');
switchNavItemsActive(4)
}
}
// 3.导航条,大纲联动(双向定位-滚动导航条定位/大纲定位)
// 导航条点击页面跳转
var navItems = getAllElem('.header__nav-item');
var outLineItems = getAllElem('.outline__item');
//setNavJump的作用是给某个元素绑定点击事件,点击该元素时,页面跳到相应的位置。
//它的参数有两个,第一个元素的索引,第二个是元素所在的dom集合。
//在setNavJump方法内,通过“dom集合[索引]”就能获取的具体要给哪个元素添加点击事件:
//以如下代码为例:
var setNavJump = function (i, lib) {
var elem = lib[i];
elem.onclick = function () {
document.body.scrollTop = i * 800;
console.log(elem);
}
}
for (var i = 0; i < navItems.length; i++) {
setNavJump(i, navItems);
}
for (var i = 0; i < outLineItems.length; i++) {
setNavJump(i, outLineItems);
}
var switchNavItemsActive = function (idx) {
// 给导航条添加active样式
for (var i = 0; i < navItems.length; i++) {
delCls(navItems[i], 'header__nav-item_status_active');
navTip.style.left = 0 + "px";
}
addCls(navItems[idx], 'header__nav-item_status_active');
//navTip.style.left = (idx * 70) + "px";
// 给大纲添加active样式
for (var i = 0; i < outLineItems.length; i++) {
delCls(outLineItems[i], 'outline__item_status_active');
//outTip.style.top = 42 + "px";
}
addCls(outLineItems[idx], 'outline__item_status_active');
//outTip.style.top = ((idx + 1) * 42) + "px";
}
switchNavItemsActive(0);
// 4.滑动门实现
var navTip = getElem(".header__nav-tip");
var outTip = getElem(".outline__nav-tip");
var setTip = function (i, dom) {
dom[i].onmouseover = function () {
console.log(i);
navTip.style.left = (i * 70) + "px";
outTip.style.top = ((i + 1) * 42) + "px";
}
var current = 0;
dom[i].onmouseout = function () {
for (var i = 0; i < dom.length; i++) {
if (getCls(dom[i]).indexOf('header__nav-item_status_active') != -1) {
current = i;
break;
}
if (getCls(dom[i]).indexOf('outline__item_status_active') != -1) {
current = i;
break;
}
}
console.log(i);
navTip.style.left = (current * 70) + "px";
outTip.style.top = ((i + 1) * 42) + "px";
}
}
for (var i = 0; i < navItems.length - 1; i++) {
setTip(i, navItems);
}
for (var i = 0; i < outLineItems.length; i++) {
setTip(i, outLineItems);
}
// 优化让第一屏默认自动播放
setTimeout(function () {
playScreenAnimateDone('.screen-1')
}, 200);
<html>
<head>
<meta charset="utf-8">
<title>慕课手机</title>
<link rel="stylesheet" type="text/css" href="./css/base.css" />
<link rel="stylesheet" type="text/css" href="./css/index.css" />
<link rel="stylesheet" type="text/css" href="./css/animate.css" />
</head>
<body>
<header class="header">
<div class="header__wrap">
<div class="header__logo">慕课手机</div>
<nav class="header__nav">
<a href="javascript:;" class="header__nav-item">首页</a>
<a href="javascript:;" class="header__nav-item">外观</a>
<a href="javascript:;" class="header__nav-item">配置</a>
<a href="javascript:;" class="header__nav-item">型号</a>
<a href="javascript:;" class="header__nav-item">说明</a>
<a href="javascript:;" class="header__nav-item header__nav-item_custom_button">立即购买</a>
<div class="header__nav-tip"></div>
</nav>
</div>
</header>
<div class="screen-1">
<h2 class="screen-1__heading screen-1__heading_animate_init"><b>慕课手机</b> 让你的生活更精彩</h2>
<div class="screen-1__phone screen-1__phone_animate_init"></div>
<div class="screen-1__shadow screen-1__shadow_animate_init"></div>
</div>
<div class="screen-2">
<h2 class="screen-2__heading">优美的设计,更令人着迷</h2>
<h3 class="screen-2__subheading">采用受欢迎的设计,让它更加出色。<br>
款式小巧、轻便手感更舒适。绚丽高清的显示屏,整个外观显得格外精致。</h3>
<div class="screen-2__phone">
<div class="screen-2__point screen-2__point_i_1">高清摄像</div>
<div class="screen-2__point screen-2__point__custom_right screen-2__point_i_2">超薄机身</div>
<div class="screen-2__point screen-2__point__custom_right screen-2__point_i_3">大屏显示</div>
</div>
</div>
<div class="screen-3">
<div class="screen-3__wrap">
<h2 class="screen-3__heading">外形小巧,功能强大的手机</h2>
<h3 class="screen-3__subheading">采用受欢迎的设计,让它更加出色。<br>
款式小巧、轻便手感更舒适。绚丽高清的显示屏,整个外观显得格外精致。</h3>
<div class="screen-3__phone"></div>
<div class="screen-3__features">
<div class="screen-3__features__item">
<div class="screen-3__features__item__number">5.7</div>
<div class="screen-3__features__item__decs">英寸大屏</div>
</div>
<div class="screen-3__features__item">
<div class="screen-3__features__item__number">1200</div>
<div class="screen-3__features__item__decs">万像素</div>
</div>
<div class="screen-3__features__item">
<div class="screen-3__features__item__number">3D</div>
<div class="screen-3__features__item__decs">touch</div>
</div>
<div class="screen-3__features__item">
<div class="screen-3__features__item__number">A9</div>
<div class="screen-3__features__item__decs">处理器</div>
</div>
</div>
</div>
</div>
<div class="screen-4">
<div class="screen-4__wrap">
<h2 class="screen-4__heading">丰富的手机型号</h2>
<h3 class="screen-4__subheading">找到适合你的手机</h3>
<div class="screen-4__type">
<div class="screen-4__type__item screen-4__type__item_i_1">
<div class="screen-4__type__item__color">慕课红</div>
<div class="screen-4__type__item__storage">32G/64G/128G</div>
</div>
<div class="screen-4__type__item screen-4__type__item_i_2">
<div class="screen-4__type__item__color">土豪金</div>
<div class="screen-4__type__item__storage">32G/64G/128G</div>
</div>
<div class="screen-4__type__item screen-4__type__item_i_3">
<div class="screen-4__type__item__color">太空灰</div>
<div class="screen-4__type__item__storage">32G/64G/128G</div>
</div>
<div class="screen-4__type__item screen-4__type__item_i_4">
<div class="screen-4__type__item__color">绅士黑</div>
<div class="screen-4__type__item__storage">32G/64G/128G</div>
</div>
</div>
</div>
</div>
<div class="screen-5">
<div class="screen-5__heading">游戏、学习、拍照,有这一部就够了</div>
<div class="screen-5__subheading">看视频、拍摄高清视频与照片、视频聊天、通话相结合,一机多功能,让您生活更丰富精彩。
</div>
<div class="screen-5__bg"></div>
</div>
<div class="screen-buy">
<a href="javascript:;" class="screen-buy__button">立即购买</a>
</div>
<footer class="footer">© 2016 imooc.com 京ICP备13046642号</footer>
<div class="outline">
<a href="javascript:;" class="outline__item">首页</a>
<a href="javascript:;" class="outline__item">外观</a>
<a href="javascript:;" class="outline__item">配置</a>
<a href="javascript:;" class="outline__item">型号</a>
<a href="javascript:;" class="outline__item">说明</a>
<div class="outline__nav-tip"></div>
</div>
<script src="js/test.js"></script>
<script src="js/index.js"></script>
</body>
</html>
/*
BEM 设计模式
模块(没有前缀,多个单词用 - 连接)
元素(元素在模块之后,可以有多个层级,以 __ 连接)
修饰(某元素、或者某模块特别的状态,必须有一个状态名和状态值,使用 _ 链接)
*/
.header {
background-color: #f7f7f7;
}
.header__wrap {
position: relative;
margin: 0 auto;
width: 1200px;
height: 80px;
}
.header__logo {
position: absolute;
top: 50%;
left: 20px;
margin-top: -19px;
width: 150px;
height: 38px;
font-size: 20px;
line-height: 38px;
color: #07111b;
text-indent: 50px;
background: url("../img/logo.png") no-repeat left center;
background-size: 38px 38px;
}
.header__nav {
position: absolute;
right: 20px;
top: 50%;
margin-top: -19px;
height: 38px;
}
.header__nav-item{
color: #292f35;
font-size: 14px;
display: block;
height: 38px;
line-height: 38px;
float: left;
position: relative;
width: 30px;
text-align: center;
/* margin: 0;*/
padding-left: 40px;
}
.header__nav-item:hover{
color: #f01400;
}
.header__nav-item_status_active{
color: #f01400;
}
.header__nav-item_status_active::after{
/* content: ' ';
display: block;
width: 100%;
height: 2px;
position: absolute;
background-color:#f01400;
left: 0;
bottom: 0;*/
}
.header__nav-item_custom_button{
background: #000;
color: #f4f4f5;
text-align: center;
width: 90px;
border-radius: 3px;
/**/
margin-left:40px;
padding: 0;
}
/* 第一屏 */
.screen-1 {
position: relative;
height: 800px;
background: url("../img/bg-screen-1.png") center center;
background-size: cover;
}
.screen-1__heading {
margin: 0;
padding: 152px 0 0 0;
font-size: 46px;
font-weight: normal;
text-align: center;
color: #4d555d;
}
.screen-1__heading b {
font-weight: normal;
color: #f01400;
}
.screen-1__phone {
position: absolute;
left: 50%;
bottom: 180px;
margin-left: -687px;
width: 1375px;
height: 305px;
background: url("../img/screen-1-phone.png") no-repeat center center;
z-index: 2;
}
.screen-1__shadow {
position: absolute;
left: 50%;
bottom: 30px;
margin-left: -616px;
width: 1233px;
height: 411px;
background: url("../img/screen-1-shadow.png") no-repeat center center;
z-index: 1;
opacity: 0.8;
}
/* 第二屏 */
.screen-2 {
position: relative;
height: 800px;
background-color: #fafafa;
overflow: hidden;
}
.screen-2__heading {
margin: 0;
padding: 96px 0 0 0;
font-size: 46px;
line-height: 46px;
font-weight: normal;
text-align: center;
color: #f01400;
}
.screen-2__subheading {
margin: 0;
padding: 25px 0 0 0;
font-size: 14px;
line-height: 28px;
font-weight: normal;
text-align: center;
color: #2c313c;
}
.screen-2__phone {
position: absolute;
left: 50%;
bottom: -345px;
margin-left: -464px;
width: 928px;
height: 873px;
background: url("../img/screen-2-phone.png") no-repeat center center;
z-index: 2;
}
.screen-2__point {
position: absolute;
padding-right: 112px;
width: 108px;
height: 22px;
font-size: 22px;
line-height: 22px;
color: #4d555d;
background: url("../img/icon-point-right.png") no-repeat center right;
}
.screen-2__point__custom_right {
padding: 0 0 0 112px;
background: url("../img/icon-point-left.png") no-repeat center left;
}
.screen-2__point_i_1 {
top: 150px;
left: -164px;
}
.screen-2__point_i_2 {
top: 30px;
right: 130px;
}
.screen-2__point_i_3 {
top: 330px;
right: 30px;
}
/* 第三屏 */
.screen-3 {
position: relative;
height: 800px;
background: url("../img/bg-screen-3.png") center center;
background-size: cover;
overflow: hidden;
}
.screen-3__wrap {
position: relative;
margin: 0 auto;
width: 1200px;
height: auto;
}
.screen-3__heading {
padding-top: 94px;
font-size: 46px;
line-height: 46px;
text-align: left;
color: #fff;
}
.screen-3__subheading {
padding-top: 25px;
font-size: 14px;
line-height: 28px;
text-align: left;
color: #fff;
}
.screen-3__phone {
position: absolute;
top: 195px;
right: 0;
bottom: -345px;
width: 750px;
height: 873px;
background: url("../img/screen-3-phone.png") no-repeat center top;
z-index: 2;
}
.screen-3__features {
position: absolute;
top: 395px;
left: 0;
width: 324px;
height: 280px;
}
.screen-3__features__item {
float: left;
margin: 0 20px 20px 0;
width: 138px;
height: 118px;
text-align: center;
border: 1px solid #cb7173;
border-radius: 3px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
-ms-border-radius: 3px;
-o-border-radius: 3px;
color: #fff;
}
.screen-3__features__item__number {
padding: 28px 0 8px;
height: 36px;
font-size: 36px;
line-height: 36px;
}
.screen-3__features__item__desc {
height: 14px;
font-size: 14px;
line-height: 14px;
}
/* 第四屏 */
.screen-4 {
position: relative;
height: 800px;
background-color: #fff;
overflow: hidden;
}
.screen-4__wrap {
position: relative;
margin: 0 auto;
width: 1200px;
height: auto;
}
.screen-4__heading {
padding-top: 135px;
font-size: 46px;
line-height: 46px;
text-align: center;
color: #f01400;
}
.screen-4__subheading {
padding-top: 29px;
font-size: 14px;
line-height: 28px;
text-align: center;
color: #464a4f;
}
.screen-4__type {
position: absolute;
top: 304px;
width: 1260px;
height: 270px;
margin-left: 40px;
}
.screen-4__type__item {
width: 220px;
margin-right: 90px;
height: 270px;
float: left;
position: relative;
text-align: center;
background-size: cover;
}
.screen-4__type__item_i_1 {
background: url(../img/phone-1.png) no-repeat left top;
}
.screen-4__type__item_i_2 {
background: url(../img/phone-2.png) no-repeat left top;
}
.screen-4__type__item_i_3 {
background: url(../img/phone-3.png) no-repeat left top;
}
.screen-4__type__item_i_4 {
background: url(../img/phone-4.png) no-repeat left top;
}
.screen-4__type__item__color {
width: 100%;
height: 14px;
line-height: 14px;
font-size: 14px;
color: #2c3238;
position: absolute;
bottom: -44px;
}
.screen-4__type__item__storage {
width: 100%;
height: 12px;
line-height: 12px;
font-size: 12px;
color: #a4a9a1;
position: absolute;
bottom: -66px;
}
/* 第五屏 */
.screen-5 {
position: relative;
height: 800px;
background-color: #d9dde1;
overflow: hidden;
}
.screen-5__bg {
width: 1920px;
height: 433px;
background: url("../img/bg-screen-5.png") no-repeat center;
background-size: contain;
position: absolute;
bottom: -100px;
left: 50%;
margin-left: -960px;
}
.screen-5__heading {
padding-top: 130px;
font-size: 46px;
line-height: 46px;
text-align: center;
color: #f01400;
}
.screen-5__subheading {
padding-top: 29px;
font-size: 14px;
line-height: 28px;
text-align: center;
color: #464a4f;
}
/* 第六屏 */
.screen-buy {
position: relative;
/* height: 320px; */
height: 80px;
padding: 120px 0 120px 0;
background: #2b333b url("../img/bg-screen-buy.png") no-repeat center center;
background-size: cover;
overflow: hidden;
text-align: center;
}
.screen-buy__button {
display: inline-block;
height: 80px;
width: 240px;
font-size: 24px;
line-height: 80px;
text-align: center;
color: #fff;
background-color: #f01414;
border-radius: 3px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
-ms-border-radius: 3px;
-o-border-radius: 3px;
/* 为hover效果添加一个效果 使得hover不这么生硬 */
transition: all 0.5s;
-webkit-transition: all 0.5s;
-moz-transition: all 0.5s;
-ms-transition: all 0.5s;
-o-transition: all 0.5s;
}
.screen-buy__button:hover {
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
}
/* 底部 */
.footer {
height: 80px;
text-align: center;
color: #fff;
font-size: 12px;
line-height: 80px;
background-color: #07111b;
}
/* outline css */
.outline {
position: fixed;
padding: 5px 10px;
bottom: 120px;
right: 0;
z-index: 3;
background-color: #fff;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
}
.outline__item {
display: block;
width: 40px;
height: 30px;
line-height: 30px;
padding: 5px 0;
background-color: #fff;
/* margin-top: 5px; */
border-top: 1px solid #eee;
color: #939992;
}
.outline__item:first-child {
border: none;
}
.outline__item:hover,
.outline__item_status_active {
color: #f01400;
}
/* 导航条样式设置 */
.header {
transition: all 1s;
-webkit-transition: all 1s;
-moz-transition: all 1s;
-ms-transition: all 1s;
-o-transition: all 1s;
}
.header_status_back {
position: fixed;
top: 0;
left: 0;
right: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 3;
}
.header_status_back .header__nav-item,
.header_status_back .header__logo {
color: #fff;
}
.header_status_back .header__nav-item_status_active {
color: red;
}
.header_status_back .header__nav-item:hover {
transition: all 1s;
color: red;
}
/* 大纲出现 */
.outline {
transform: translate(100%, 0);
transition: all 1s;
}
.outline_status_in {
transform: translate(0, 0);
}
.outline__item {
transition: all 1s;
}
/* 滑动门css */
.header__nav-tip {
position: absolute;
width: 30px;
margin-left: 40px;
height: 2px;
background: #f00;
left: 0;
bottom: 0px;
transition: all .5s;
-webkit-transition: all .5s;
-moz-transition: all .5s;
-ms-transition: all .5s;
-o-transition: all .5s;
}
.outline__nav-tip{
position: absolute;
width: 40px;
margin-left: 10px;
height: 2px;
background: #f00;
left: 0;
bottom: 0px;
transition: all 1s;
-webkit-transition: all 1s;
-moz-transition: all 1s;
-ms-transition: all 1s;
-o-transition: all 1s;
}
1回答
同学你好,对于你的问题解答如下:截图中控制台报错的原因是:switchNavItemsActive方法中使用navTip时,还没有获取到navTip元素,无法设置样式,导致报错。
建议:将获取navTip元素的代码调整到前面。
调整后,打开注释的代码,滚动时滑动门效果就可以实现了。如下所示:
祝学习愉快~
相似问题