Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

offset().top Not Working Properly

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.

<!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});
    });
like image 942
Mike Zhu Avatar asked May 10 '15 10:05

Mike Zhu


2 Answers

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)

// 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.

like image 124
JohnDevelops Avatar answered Oct 18 '22 03:10

JohnDevelops


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;

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!

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!

like image 1
78juli Avatar answered Oct 18 '22 05:10

78juli