允许在滚动动画期间改变元素高度
Allowing for changes in element height during a scroll animation
有一个 JS/JQuery 我正在努力解决的问题。
我正在构建一个简单的单页网站,该网站具有固定的 header 和基于锚点的滚动导航。当用户单击 link 时,body 的 scrollTop 会动画到相关部分的顶部。此函数中包含一项计算,即从滚动距离中减去 header 的高度,以确保固定的 header 不会遮挡部分
的顶部
我遇到的问题是因为一个单独的函数在用户滚动超过一定距离时将 class 应用于 header。 class 会导致一些属性发生变化,因此 header 元素的高度也会发生变化。
这意味着滚动动画结束时$('header').outerHeight();
的值小于动画开始时的值。此更改意味着滚动的距离是错误的,并且 window 最终距离所需位置稍微太短了。
如何允许在滚动动画期间更改值?理想情况下,我希望一切都保持动态而不是指定固定 heights/sizes。 TIA.
$('a[href^="#"]').on("click", function() {
let headerHeight = $('header').outerHeight();
$('html, body').animate({
scrollTop: $($.attr(this, 'href')).offset().top - headerHeight
}, 500);
});
$(window).on('load resize scroll', function() {
if ($(window).scrollTop() >= 100 ) { // this refers to window
$('header').addClass('scroll');
} else {
$('header').removeClass('scroll');
}
});
body,html {
margin: 0;
padding: 0;
}
header {
padding: 30px 30px;
position:fixed;
left:0;
right: 0;
top: 0;
z-index:99;
transition: all .3s ease;
}
header h1 {
display:inline-block;
width:10%;
color: white;
}
header.scroll {
background: black;
padding: 15px 30px;
}
header nav {
display:inline-block;
width: 89%;
}
header nav ul {
margin: 0;
list-style: none;
text-align:right;
}
header nav ul li {
display:inline-block;
}
header nav ul li a {
color: white;
padding: 0 10px;
}
.hero {
height: 600px;
background: blue;
}
section h2 {
position: relative;
top: 50%;
transform: translateY(-50%);
margin: 0;
text-align: center;
color: white;
}
section {
height: 600px;
}
#one {
background: red;
}
#two {
background: green;
}
#three {
background: orange;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header>
<h1>Title</h1>
<nav>
<ul>
<li><a href="#one">Section 1 </a></li>
<li><a href="#two">Section 2 </a></li>
<li><a href="#three">Section 3 </a></li>
</ul>
</nav>
</header>
<section class="hero"><h2>Hero</h2></section>
<section id="one"><h2>Section 1</h2></section>
<section id="two"><h2>Section 2</h2></section>
<section id="three"><h2>Section 3</h2></section>
如果您 运行 上述代码段并单击页面顶部 "Section 1" 的 link。您可以看到滚动的距离有点太短,并且由于高度的变化,.hero
元素的底部仍然可见。
试试这个,我从 header 的高度中减去 30,因为开始填充是“30px 30px”,然后它会是“15px 30px”,这意味着 header 高度应该是:
height = 实际高度 - - ,
当您的 header 展开时需要这样做(意味着 header 没有 class 滚动条)所以我添加了条件。
$('a[href^="#"]').on("click", function() {
let headerHeight = $('header').outerHeight();
if(!$('header').hasClass('scroll')) {
headerHeight -= 30; //The padding removed
}
$('html, body').animate({
scrollTop: $($.attr(this, 'href')).offset().top - headerHeight
}, 500);
});
$(window).on('load resize scroll', function() {
if ($(window).scrollTop() >= 100 ) { // this refers to window
$('header').addClass('scroll');
} else {
$('header').removeClass('scroll');
}
});
body,html {
margin: 0;
padding: 0;
}
header {
padding: 30px 30px;
position:fixed;
left:0;
right: 0;
top: 0;
z-index:99;
transition: all .3s ease;
}
header h1 {
display:inline-block;
width:10%;
color: white;
}
header.scroll {
background: black;
padding: 15px 30px;
}
header nav {
display:inline-block;
width: 89%;
}
header nav ul {
margin: 0;
list-style: none;
text-align:right;
}
header nav ul li {
display:inline-block;
}
header nav ul li a {
color: white;
padding: 0 10px;
}
.hero {
height: 600px;
background: blue;
}
section h2 {
position: relative;
top: 50%;
transform: translateY(-50%);
margin: 0;
text-align: center;
color: white;
}
section {
height: 600px;
}
#one {
background: red;
}
#two {
background: green;
}
#three {
background: orange;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header>
<h1>Title</h1>
<nav>
<ul>
<li><a href="#one">Section 1 </a></li>
<li><a href="#two">Section 2 </a></li>
<li><a href="#three">Section 3 </a></li>
</ul>
</nav>
</header>
<section class="hero"><h2>Hero</h2></section>
<section id="one"><h2>Section 1</h2></section>
<section id="two"><h2>Section 2</h2></section>
<section id="three"><h2>Section 3</h2></section>
通过向我的动画函数添加回调最终解决了这个问题。回调检查 header 的高度自函数首次调用以来是否发生变化,如果发生变化,则 scrollTop 增加此数量。
$('a[href^="#"]').on("click", function() {
let headerHeightOne = $('header').outerHeight();
$('html, body').animate({
scrollTop: $($.attr(this, 'href')).offset().top - headerHeightOne
}, 500, function() {
let headerHeightTwo = $('header').outerHeight();
let difference = headerHeightOne - headerHeightTwo;
if (difference > 0 ) {
$('html,body').animate({
scrollTop: $(window).scrollTop() + difference
}, 100);
}
});
});
有一个 JS/JQuery 我正在努力解决的问题。
我正在构建一个简单的单页网站,该网站具有固定的 header 和基于锚点的滚动导航。当用户单击 link 时,body 的 scrollTop 会动画到相关部分的顶部。此函数中包含一项计算,即从滚动距离中减去 header 的高度,以确保固定的 header 不会遮挡部分
的顶部我遇到的问题是因为一个单独的函数在用户滚动超过一定距离时将 class 应用于 header。 class 会导致一些属性发生变化,因此 header 元素的高度也会发生变化。
这意味着滚动动画结束时$('header').outerHeight();
的值小于动画开始时的值。此更改意味着滚动的距离是错误的,并且 window 最终距离所需位置稍微太短了。
如何允许在滚动动画期间更改值?理想情况下,我希望一切都保持动态而不是指定固定 heights/sizes。 TIA.
$('a[href^="#"]').on("click", function() {
let headerHeight = $('header').outerHeight();
$('html, body').animate({
scrollTop: $($.attr(this, 'href')).offset().top - headerHeight
}, 500);
});
$(window).on('load resize scroll', function() {
if ($(window).scrollTop() >= 100 ) { // this refers to window
$('header').addClass('scroll');
} else {
$('header').removeClass('scroll');
}
});
body,html {
margin: 0;
padding: 0;
}
header {
padding: 30px 30px;
position:fixed;
left:0;
right: 0;
top: 0;
z-index:99;
transition: all .3s ease;
}
header h1 {
display:inline-block;
width:10%;
color: white;
}
header.scroll {
background: black;
padding: 15px 30px;
}
header nav {
display:inline-block;
width: 89%;
}
header nav ul {
margin: 0;
list-style: none;
text-align:right;
}
header nav ul li {
display:inline-block;
}
header nav ul li a {
color: white;
padding: 0 10px;
}
.hero {
height: 600px;
background: blue;
}
section h2 {
position: relative;
top: 50%;
transform: translateY(-50%);
margin: 0;
text-align: center;
color: white;
}
section {
height: 600px;
}
#one {
background: red;
}
#two {
background: green;
}
#three {
background: orange;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header>
<h1>Title</h1>
<nav>
<ul>
<li><a href="#one">Section 1 </a></li>
<li><a href="#two">Section 2 </a></li>
<li><a href="#three">Section 3 </a></li>
</ul>
</nav>
</header>
<section class="hero"><h2>Hero</h2></section>
<section id="one"><h2>Section 1</h2></section>
<section id="two"><h2>Section 2</h2></section>
<section id="three"><h2>Section 3</h2></section>
如果您 运行 上述代码段并单击页面顶部 "Section 1" 的 link。您可以看到滚动的距离有点太短,并且由于高度的变化,.hero
元素的底部仍然可见。
试试这个,我从 header 的高度中减去 30,因为开始填充是“30px 30px”,然后它会是“15px 30px”,这意味着 header 高度应该是: height = 实际高度 - - , 当您的 header 展开时需要这样做(意味着 header 没有 class 滚动条)所以我添加了条件。
$('a[href^="#"]').on("click", function() {
let headerHeight = $('header').outerHeight();
if(!$('header').hasClass('scroll')) {
headerHeight -= 30; //The padding removed
}
$('html, body').animate({
scrollTop: $($.attr(this, 'href')).offset().top - headerHeight
}, 500);
});
$(window).on('load resize scroll', function() {
if ($(window).scrollTop() >= 100 ) { // this refers to window
$('header').addClass('scroll');
} else {
$('header').removeClass('scroll');
}
});
body,html {
margin: 0;
padding: 0;
}
header {
padding: 30px 30px;
position:fixed;
left:0;
right: 0;
top: 0;
z-index:99;
transition: all .3s ease;
}
header h1 {
display:inline-block;
width:10%;
color: white;
}
header.scroll {
background: black;
padding: 15px 30px;
}
header nav {
display:inline-block;
width: 89%;
}
header nav ul {
margin: 0;
list-style: none;
text-align:right;
}
header nav ul li {
display:inline-block;
}
header nav ul li a {
color: white;
padding: 0 10px;
}
.hero {
height: 600px;
background: blue;
}
section h2 {
position: relative;
top: 50%;
transform: translateY(-50%);
margin: 0;
text-align: center;
color: white;
}
section {
height: 600px;
}
#one {
background: red;
}
#two {
background: green;
}
#three {
background: orange;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header>
<h1>Title</h1>
<nav>
<ul>
<li><a href="#one">Section 1 </a></li>
<li><a href="#two">Section 2 </a></li>
<li><a href="#three">Section 3 </a></li>
</ul>
</nav>
</header>
<section class="hero"><h2>Hero</h2></section>
<section id="one"><h2>Section 1</h2></section>
<section id="two"><h2>Section 2</h2></section>
<section id="three"><h2>Section 3</h2></section>
通过向我的动画函数添加回调最终解决了这个问题。回调检查 header 的高度自函数首次调用以来是否发生变化,如果发生变化,则 scrollTop 增加此数量。
$('a[href^="#"]').on("click", function() {
let headerHeightOne = $('header').outerHeight();
$('html, body').animate({
scrollTop: $($.attr(this, 'href')).offset().top - headerHeightOne
}, 500, function() {
let headerHeightTwo = $('header').outerHeight();
let difference = headerHeightOne - headerHeightTwo;
if (difference > 0 ) {
$('html,body').animate({
scrollTop: $(window).scrollTop() + difference
}, 100);
}
});
});