javascript offset().top 不能正常工作
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30150528/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
offset().top Not Working Properly
提问by Mike Zhu
Basically I am working on a one-page website and I would like to include the menu in this website. When the user clicks the link, the page will scroll to the anchor. But it seems that every time the page just doesn't scroll to the right position. The value it returns from offset().top
is smaller than the real position. I checked many online tutorials but still can't figure it out.
基本上我在一个单页网站上工作,我想在这个网站中包含菜单。当用户点击链接时,页面将滚动到锚点。但似乎每次页面都没有滚动到正确的位置。它返回的值offset().top
小于实际位置。我查了很多在线教程,但仍然无法弄清楚。
<!DOCTYPE html>
<html>
<head>
<title>Letsport</title>
<meta charset = "UTF-8">
<link rel="stylesheet" type="text/css" href="style/normalize.css">
<link href='http://fonts.googleapis.com/css?family=Lobster' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Open+Sans:400,600,700' rel='stylesheet' type='text/css'>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script type="text/javascript" src = "script/script.js"></script>
</head>
<body>
<nav id = "side_nav">
<div id = "nav_content">
<div id = "cross_btn">
<a href="#">
<img src="img/cross.png">
</a>
</div>
<ul>
<li><a href="#" id = "home_link">HOME</a></li>
<li><a href="#" id = "download_link">DOWNLOAD</a></li>
<li><a href="#" id = "contact_link">CONTACT</a></li>
</ul>
</div>
</nav>
<div id = "overlay">
</div>
<section id = "home_section">
<ul>
<li id = "logo">
<img src="img/logo.png">
</li>
<li id = "stripes">
<div id = "stripe_background">
<a href="#">
<div>
<div class = "stripe"></div>
<div class = "stripe"></div>
<div class = "stripe"></div>
</div>
</a>
</div>
</li>
</ul>
<div id = "title">
<div id = "bar_up"></div>
<h1>
Letsport
</h1>
<div id = "bar_down"></div>
<div id = "slider_wrapper">
<div id = "text_slider">
<div><h2>TEAMMATES NOT SHOWING UP?</h2></div>
<div><h2>HARD TO BOOK ONLINE?</h2></div>
<div><h2>WANNA SEEK A COMPETITOR IN THE SAME LEVEL?</h2></div>
<div><h2>COME AND DOWNLOAD LETSPORT!</h2></div>
</div>
</div>
</div>
<video id = "home_video" autoplay loop>
<source src = "media/home_video.mp4">
</video>
</section>
<section id = "video_section">
<div class = "section_content">
<h1>DO YOU HAVE SAME TROUBLES?</h1>>
<div id = "interview_video">
<ul>
<li>
<video class = "each_video" class = "filter" id = "video1" loop>
<source src = "media/1.mp4">
</video>
</li>
<li>
<video class = "each_video" class = "filter" id = "video2" loop>
<source src = "media/2.mp4">
</video>
</li>
</ul>
<ul>
<li>
<video class = "each_video" class = "filter" id = "video3" loop>
<source src = "media/3.mp4">
</video>
</li>
<li>
<video class = "each_video" class = "filter" id = "video4" loop>
<source src = "media/4.mp4">
</video>
</li>
</ul>
</div>
</div>
</section>
<section id = "about_section">
<div class = "section_content">
<ul>
<li id = "about_desc" class = "about hidden">
<h1>TIRED</h1>
<h2>OF THESE PROBLEMS?</h2>
<h3>DOWNLOAD "LETSPORT" TO HELP YOU!</h3>
<p>"Letsport" is a mobile application which helps you to find your sportmates. Besides, you can even book online! Download "Letsport" and enjoy!</p>
</li>
<li id = "mock_up">
<img src="img/mockup.png">
</li>
</ul>
</div>
</section>
</body>
</html>
body {
margin: 0;
font-family: 'Open Sans', sans-serif;
color: white;
height: 100%;
width: 100%;
position: relative;
}
a {
text-decoration: none;
}
h1 {
padding: 30px 0 0 0;
margin: 0;
font-weight: 700;
font-size: 2.5em;
}
h2 {
margin: 0px;
font-weight: 600;
font-size: 1.3em;
}
ul {
list-style: none;
}
.section_content {
width: 95%;
margin: 0 auto;
padding: 100px 0;
text-align: center;
}
#side_nav {
position: fixed;
top: 0;
right: -500px;
width: 500px;
height: 100%;
background-color: rgba(0, 0, 0, 0.9);
z-index: 100;
}
#side_nav li {
padding: 5px 0;
}
#side_nav li a {
color: white;
font-size: 1.5em;
letter-spacing: 0.3em;
}
#side_nav li a:hover {
color: yellow;
text-decoration: underline;
}
#side_nav #nav_content {
margin: 15px;
}
#side_nav #nav_content #cross_btn {
padding: 10px;
}
#overlay {
display: none;
top: 0;
left: 0;
position: fixed;
width: 100%;
height: 100%;
background-color: rgba(255, 255, 255, 0.3);
}
/******************************************
HOME SECTION
******************************************/
#home_section {
width: 100%;
height: 720px;
}
#home_section ul {
width: 100%;
padding: 0;
}
#home_section ul li {
display: inline-block;
}
#logo {
margin: 15px;
}
#stripes {
position: fixed;
right: 0;
top: 0;
margin: 15px;
float: right;
}
#stripe_background {
padding: 10px;
}
.active_stripe {
background-color: rgba(0, 0, 0, 0.5);
}
.stripe {
width: 30px;
height: 3px;
margin: 5px 0;
background-color: white;
}
#home_section #home_video {
position: fixed;
top: 0;
left: 0;
min-width: 100%;
min-height: 100%;
width: auto;
height: auto;
z-index: -100;
background-size: cover;
filter: brightness(35%);
-webkit-filter: brightness(35%);
-moz-filter: brightness(35%);
-ms-filter: brightness(35%);
-o-filter: brightness(35%);
}
#home_section #title {
margin: 150px auto;
text-align: center;
}
#home_section #title h1 {
padding: 15px 0 30px 0;
margin: 0;
font-family: 'Lobster', cursive;
font-size: 6em;
}
#home_section #title #bar_up {
position: fixed;
left: 50%;
width: 50%;
height: 2px;
margin: 0 0 0 -25%;
background-color: white;
}
#home_section #title #bar_down {
position: fixed;
left: 50%;
width: 50%;
height: 2px;
margin: 0 0 0 -25%;
background-color: white;
}
#home_section #title h2 {
margin-top: 30px;
font-weight: 400;
font-size: 1.3em;
letter-spacing: 0.5em;
color: #cecece;
}
#slider_wrapper {
width: 60%;
position: relative;
margin: 0 auto;
}
#text_slider div {
width: 100%;
position: absolute;
text-align: center;
}
/******************************************
VIDEO SECTION
******************************************/
#video_section {
background-color: white;
}
#video_section h1 {
color: #333333;
}
#video_section h2 {
color: #505050;
}
.each_video {
width: 200px;
filter: brightness(35%);
-webkit-filter: brightness(35%);
-moz-filter: brightness(35%);
-ms-filter: brightness(35%);
-o-filter: brightness(35%);
}
.filter {
filter: brightness(100%);
-webkit-filter: brightness(100%);
-moz-filter: brightness(100%);
-ms-filter: brightness(100%);
-o-filter: brightness(100%);
-webkit-transition: 1s -webkit-filter linear;
-moz-transition: 1s -moz-filter linear;
-moz-transition: 1s filter linear;
-ms-transition: 1s -ms-filter linear;
-o-transition: 1s -o-filter linear;
transition: 1s filter linear;
}
#video_section ul {
margin: 0;
}
#video_section ul li {
display: inline-block;
padding: 0;
}
/******************************************
ABOUT SECTION
******************************************/
#about_section {
background-color: #5489dd;
margin-top: 0;
position: relative;
}
#about_section ul {
margin: 0;
}
#about_section ul li {
width: 500px;
display: inline-block;
vertical-align: top;
}
#about_section ul #about_desc {
text-align: right;
}
#about_section ul #about_desc h1 {
margin: 0;
padding-bottom: 0;
font-size: 8em;
}
#about_section ul #about_desc h2 {
font-size: 2em;
}
.about {
transform-style: preserve-3d;
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
-ms-transform-style: preserve-3d;
-o-transform-style: preserve-3d;
transform: perspective(1000px);
-webkit-transform: perspective(1000px);
-moz-transform: perspective(1000px);
-ms-transform: perspective(1000px);
-o-transform: perspective(1000px);
}
.about h1, .about h2, .about h3, .about p {
transition: all 0.8s ease;
-webkit-transition: all 0.8s ease;
-moz-transition: all 0.8s ease;
-ms-transition: all 0.8s ease;
-o-transition: all 0.8s ease;
}
.about.hidden h1, .about.hidden h2, .about.hidden h3, .about.hidden p {
opacity: 1;
transform: translate3d(0, 0, 400px) rotateY(40deg);
-webkit-transform: translate3d(0, 0, 400px) rotateY(40deg);
-moz-transform: translate3d(0, 0, 400px) rotateY(40deg);
-ms-transform: translate3d(0, 0, 400px) rotateY(40deg);
-o-transform: translate3d(0, 0, 400px) rotateY(40deg);
}
$(document).ready(function(){
var homeSectionTopPosY = $('#home_section').offset().top,
videoSectionTopPosY = $('#video_section').offset().top,
chooseSectionTopPosY = $('#choose_section').offset().top,
joinSectionTopPosY = $('#join_section').offset().top,
makeUpSectionTopPosY = $('#make_up_section').offset().top,
downloadSectionTopPosY = $('#download_section .section_content h1').offset().top,
contactSectionTopPosY = $('#contact_section').offset().top,
aboutSectionTopPosY = $('#about_section').offset().top;
// Anchor to the position
$('#home_link').on('click', function(){
$('html, body').animate({scrollTop: 0});
});
$('#download_link').on('click', function(){
$('html, body').animate({scrollTop: chooseSectionTopPosY});
});
$('#contact_link').on('click', function(){
$('html, body').animate({scrollTop: contactSectionTopPosY});
});
回答by JohnDevelops
I've worked on a few single-page sites recently and have changed my approach to it a few times. Currently I use this method:
我最近在几个单页网站上工作过,并多次改变了我的方法。目前我使用这种方法:
// Scroll smoothly to an element
function smooth_scroll_to(elem)
{
var offset = 0;
offset = $(elem).offset().top;
$('html, body').animate({
scrollTop: offset
}, 550);
}
// Initiate smooth scroll to area based on navigation item title attr
$('#side_nav li a').click(function(e){
e.preventDefault();
var elem = $(this).attr('title');
smooth_scroll_to(elem);
});
// Add title="#IDOFELEMENT" to each nav item
<ul>
<li><a title="#home_section" href="#" id = "home_link">HOME</a></li>
<li><a title="#download_section" href="#" id = "download_link">DOWNLOAD</a></li>
<li><a title="#contact_section" href="#" id = "contact_link">CONTACT</a></li>
</ul>
Using HREF seems more user friendly and cleaner. (Credit to @KarelG)
使用 HREF 看起来更用户友好和更干净。(归功于@KarelG)
// Always use ID's and only place the text portion in the title
<li><a href="#home_section" id="home_link">HOME</a></li>
var elem = $(this).attr('href');
This will also allow for navigation in the event of a JS error or similar preventing the animation.
这也将允许在 JS 错误或类似阻止动画的情况下进行导航。
回答by 78juli
I've run into the same problem, trying to implement a current menu item highlight for a one page site when being at a section which has an ID which is part of the menu. In this case instead of offset = $(elem).offset().top;
I had secPosition = $(theID).offset().top;
我遇到了同样的问题,当处于一个具有作为菜单一部分的 ID 的部分时,我试图为单页站点实现当前菜单项突出显示。在这种情况下,而不是 offset = $(elem).offset().top;
我有secPosition = $(theID).offset().top;
Here is the original snippet: Source
这是原始片段:来源
<script type="text/javascript">
(function($) {
$(document).ready(function() {
var navChildren = $("#top-menu li").children();
var aArray = [];
for (var i = 0; i < navChildren.length; i++) {
var aChild = navChildren[i];
var ahref = $(aChild).attr('href');
aArray.push(ahref);
}
$(window).scroll(function() {
var windowPos = $(window).scrollTop();
var windowHeight = $(window).height();
var docHeight = $(document).height();
for (var i = 0; i < aArray.length; i++) {
var theID = aArray[i];
var secPosition = $(theID).offset().top;
secPosition = secPosition - 135;
var divHeight = $(theID).height();
divHeight = divHeight + 90;
if (windowPos >= secPosition && windowPos < (secPosition + divHeight)) {
$("a[href='" + theID + "']").parent().addClass("active");
} else {
$("a[href='" + theID + "']").parent().removeClass("active");
}
}
});
});
})(jQuery);
</script>
The secPosition
value was calculated completely wrong all the time, I've checked in the chrome debugger. Then what helped me was also to initialise the secPosition variable with 0 as the value, as described above by JohnDevelops. I don't quite understand why it makes a difference but it does work!
该secPosition
值一直计算完全错误,我已经检查了 chrome 调试器。然后帮助我的是使用 0 作为值初始化 secPosition 变量,如 JohnDevelops 上面所述。我不太明白为什么它会有所不同,但它确实有效!
So this is the final working version:
所以这是最终的工作版本:
<script type="text/javascript">
jQuery(document).ready(function(){
jQuery("button.et_pb_contact_submit").text('Senden');
});
</script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css">
<script type="text/javascript">
(function($) {
$(document).ready(function() {
var navChildren = $("#top-menu li").children();
var aArray = [];
for (var i = 0; i < navChildren.length; i++) {
var aChild = navChildren[i];
var ahref = $(aChild).attr('href');
aArray.push(ahref);
}
$(window).scroll(function() {
var secPosition = 0;
var windowPos = $(window).scrollTop();
var windowHeight = $(window).height();
var docHeight = $(document).height();
for (var i = 0; i < aArray.length; i++) {
var theID = aArray[i];
secPosition = $(theID).offset().top;
secPosition = secPosition - 135;
var divHeight = $(theID).height();
divHeight = divHeight + 90;
if (windowPos >= secPosition && windowPos < (secPosition + divHeight)) {
$("a[href='" + theID + "']").parent().addClass("active");
} else {
$("a[href='" + theID + "']").parent().removeClass("active");
}
}
I hope this saves others time, I've spent hours on figuring this out!
我希望这可以节省其他人的时间,我已经花了几个小时来解决这个问题!
回答by Ondra Koupil
You could use one of several jQuery plugins which enables you to smoothly scroll to target element instead of measuring offset of target element and doing some calculations. Try https://github.com/flesler/jquery.scrollTo
您可以使用几个 jQuery 插件之一,它使您能够平滑滚动到目标元素,而不是测量目标元素的偏移量并进行一些计算。试试https://github.com/flesler/jquery.scrollTo