1

I'm trying to replicate this jsfiddle, which sticks the bar to the top when scrolling down; but there is something wrong which I am not able to identify.

To go to the most basic approach possible, I want to avoid links between files and therefore include everything inside the same html file, following this structure:

<html>
    <head>
        <style>
            /* css here */
        </style>
    </head>
    <body>
        <!-- html here -->
        <script>
            // javascript here
        </script>
    </body>
</html>

Here is how it looks like:

<html>
    <head>
        <style>
        html, body {
            min-height: 100%;
            padding: 0;
            margin: 0;
        }
        .stick {
            position: fixed;
            top: 0;
        }
        #a8 {
            height: 50px;
            width: 100%;
            background: #DDD;
        }
        </style>
    </head>
    <body>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <div id="a8"></div>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <script>
        var top = document.getElementById('a8').offsetTop;

        window.onscroll = function() {
            var y = (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;
            if (y >= top) {
                a8.className = 'stick';
            }
            else {
                a8.className = '';
            }
        };
        </script>
    </body>
</html>

After checking for similar questions (here, here and here), all of them refer to the fact that the page is not yet rendered when the js code runs. Placing the js at the bottom (which I have already done) should solve the problem; but anyway I have also tried wrapping js with

$(document).ready(function() {
    // code here
});

and

window.onscroll = function() {
    // code here
});

and

$(window).onload(function(){
    // code here
});

but did not help.

What am I missing?

Community
  • 1
  • 1
J0ANMM
  • 7,849
  • 10
  • 56
  • 90
  • Do you get any errors ? because copy/pasting your code in a html file seams to work. Maybe try disabling your extensions if you have any. – Bobby Tables Jan 11 '17 at 11:33
  • No errors. I tried it in Chrome (where I have many extensions) and in Firefox (where I have no extensions enabled). Didn´t work in any case. Are you getting the sticky effect by just copy-pasting my code, @robert ? – J0ANMM Jan 11 '17 at 11:43
  • Just wrap the whole thing on a `window.onload = function(){ ... };`. By that, I mean **the entire script** inside it. Including the `var ...;`! – Ismael Miguel Jan 11 '17 at 11:46
  • You mention jQuery functions in your post, but not in your code. Is there anything with a `$` in your real code? – baao Jan 11 '17 at 11:48
  • @IsmaelMiguel, as I tried that (see last piece of code in the question), this is exactly what I did. – J0ANMM Jan 11 '17 at 11:49
  • @baao , I don't get exactly your point, but this might be the way to go. The real codes are the jsfiddle one and the one posted here. I do not import an jQuery and have no background about js, so I am probably missing something there. Could you expand? – J0ANMM Jan 11 '17 at 11:52

3 Answers3

4

i found that the var name top is ambiguous with window.top which is the most top frame. so just rename it with something else like as top1 solve the problem!

var top1 = document.getElementById('a8').offsetTop;
S.Serpooshan
  • 7,608
  • 4
  • 33
  • 61
  • That's it! Thanks! Now I have the problem that both answers were almost simultaneous and correct, so I don't know which one should be the accepted one... – J0ANMM Jan 11 '17 at 12:05
  • mine was sooner than the edited version of @robert ;D but no problem as you wish – S.Serpooshan Jan 11 '17 at 12:06
  • 1
    just as note: i found the issue using the Chrome Inspect feature and putting a break-point inside the function. there, i saw that in the `if` condition the var top is an object not a number! – S.Serpooshan Jan 11 '17 at 12:10
1

Changing you script to this should do the trick.

 <script>
     var myTop = document.getElementById('a8').offsetTop;
    window.onscroll = function() {
        var y = (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;
        if (y >= myTop) {
            a8.className = 'stick';
        }
        else {
            a8.className = '';
        }
    };
</script>

My initial answer was wrong, has nothing to do with the loading but it has to do with the top property of the window.

Bobby Tables
  • 2,953
  • 7
  • 29
  • 53
  • Interesting! If I copy-past this into my code, it does work! What is the difference between those I posted above and yours? – J0ANMM Jan 11 '17 at 11:54
  • 1
    @Nit0 The reason the other version worked as well(and the fiddle) was because when you where in function the top local variable took precedence over the property of the window – Bobby Tables Jan 11 '17 at 12:02
  • Unterstood. Thanks!! – J0ANMM Jan 11 '17 at 12:03
  • yes, it is due to the `top` var name as i mentioned in my posted ans 3 minutes sooner than your edit! ;D – S.Serpooshan Jan 11 '17 at 12:03
  • @S.Serp well you've got my upvote, medals I can't give. – Bobby Tables Jan 11 '17 at 12:06
  • Thanks a lot for you help. I made S.Serp's answer the accepted one, as he was apparently first and his answer goes more to the point. Anyway, I appreciate your time! :) – J0ANMM Jan 11 '17 at 12:12
0

It was issue with top variable but in other case when you need something to execute after page load is complete then you may wrap your script in function

document.addEventListener('DOMContentLoaded', function() {
   // your code here
}, false);

This will also work.

    document.addEventListener('DOMContentLoaded', function() {
        var top = document.getElementById('a8').offsetTop;

    window.onscroll = function() {
        var y = (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;
        if (y >= top) {
            a8.className = 'stick';
        }
        else {
            a8.className = '';
        }
    };
    }, false);
Aqdas
  • 868
  • 4
  • 16
  • 57