Floating menu fixed [closed] - javascript

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I want to create a floating menu that will stay on top when scrolling. I found some examples and was able to replicate them and it now works.
However, the problem is that as you can see in the example, when I scroll, the text below the menu when scrolling "jumps up", it is difficult to explain what I mean, but if you look at it, you will immediately see what the problem is. Could anyone help me with fixing this?

Add .sectionHeading a dynamic margin:top equal to the height of the menu, with the same event that triggers the fixed class.

You need to do this on a trial and error basis. And you need to change a static parent. Check this example and follow it.
Snippet
$(function () {
$(window).scroll(function () {
if ($(window).scrollTop() > 125)
$("body").addClass("fixed");
else
$("body").removeClass("fixed");
});
});
* {font-family: 'Segoe UI'; margin: 0; padding: 0; list-style: none;}
h1, h2 {font-weight: normal;}
h1 {font-size: 1.5em;}
h2 {font-size: 1.25em;}
h1, h2, p {margin: 0 0 15px;}
.fixed {padding-top: 42px;}
.fixed .static {position: fixed; top: 0; width: 100%; background: #fff; padding-bottom: 15px;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h1>Static Header Example</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. At, cumque inventore laudantium quod, vel pariatur dolore obcaecati veniam aspernatur aliquam ad dolorum possimus illo facilis et totam nam unde, sint?</p>
<h2 class="static">This is gonna be Static!</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Officiis tempore praesentium eos odio nobis dignissimos labore expedita corrupti sapiente perferendis consequuntur, in, eveniet error! Officiis iste architecto eos? Deserunt, delectus!</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Velit, blanditiis dolore ipsum odit sint delectus assumenda excepturi dolor rem aperiam magni eligendi quidem suscipit nam ullam porro tenetur tempora ut!</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Officiis tempore praesentium eos odio nobis dignissimos labore expedita corrupti sapiente perferendis consequuntur, in, eveniet error! Officiis iste architecto eos? Deserunt, delectus!</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Velit, blanditiis dolore ipsum odit sint delectus assumenda excepturi dolor rem aperiam magni eligendi quidem suscipit nam ullam porro tenetur tempora ut!</p>

When you're changing the class of the your menu from default to fixed the height of your document will reduce by the height of your menu because you have changed the display of your menu.
The solution is that when you change the class of the menu from default to fixed you can add some padding to your document's body (the height of the menu element is fine) and remove the padding when changing the class of the menu from fixed to default.
$(function(){
var menu = $('#menu'),
pos = menu.offset();
$(window).scroll(function(){
if($(this).scrollTop() > pos.top && menu.hasClass('default')){
menu.hide(1, function(){
$(this).removeClass('default').addClass('fixed').show(1);
$('body').css('padding-top', '111px');
});
} else if($(this).scrollTop() <= pos.top && menu.hasClass('fixed')){
menu.hide(1, function(){
$(this).removeClass('fixed').addClass('default').show(1);
$('body').css('padding-top', '0');
});
}
});
});

You can add another div like your menu but with class="fixed" and display: none, when the scroll reaches the top of the page, you can show that div and change the visibility of the #menu from visible to hidden.

Related

scroll step is different in Firefox - with mouse wheel

I'm making a website with huge text on screen & I would like to be able to scroll two divs at the same time. So this part is working.
I'm actually able to scroll the divs but the jumps are really too huge on the #back div. (they seems to actually be the same as the window height (so maybe you need to have the snipped full screen to fully understand what I mean)).
UPDATE: after a bit of testing with a friend, the issue appears to be with firefox on windows. It's working just fine on mac & linux.
here is a fiddle so you can see with a increased height
Here are two gif so maybe you see the weird effet.
each page movement = one scrollwheel down on my mouse (also it's working just fine with a trackpad since it's not a mouse wheel).
VS when I remove one of the two overflow in my css, my following black square stops working, but the scroll is normal again :
IMPORTANT EDIT : This is an issue in firefox but it seems to be working correctly in chrome & Brave. I'm still looking for a way to make it work nonetheless.
So, I noticed that this happens when I set two overflows in the css, actually, if you remove one, the script doesn't work anymore but the scroll bug is stopping too.
Here is the example with the bug:
let back_innerHeight = $("#back").height()
let back_scrollHeight = document.querySelector("#back").scrollHeight
let front_innerHeight = $("#front").innerHeight()
let front_scrollHeight = $("#front")[0].scrollHeight
$("#back").on("scroll", function () {
// Get how many pixels were scrolled on #back
let back_scrolled = $(this).scrollTop()
// Calculate the scrolled percentage
let percentage_back = back_scrolled / (back_scrollHeight - back_innerHeight)
// Calculate how many pixels to scroll on #front
let scrollIT = (percentage_back * (front_scrollHeight - front_innerHeight))
// Just to validate that the percentage is applied correctly...
let percentage_front = scrollIT / (front_scrollHeight - front_innerHeight)
// Apply the scroll
$("#front").scrollTop(scrollIT);
});
window.onresize = function(){
back_innerHeight = $("#back").height()
back_scrollHeight = document.querySelector("#back").scrollHeight
front_innerHeight = $("#front").innerHeight()
front_scrollHeight = $("#front")[0].scrollHeight
}
.scroll {
position: absolute;
display: block;
top: 0;
height: 100%;
}
#front {
overflow: hidden;
position: absolute;
background-color: black;
color: white;
right: 0;
left: 0;
bottom: 0;
top: 0;
margin: auto auto auto auto;
width: 25%;
height: 35%;
font-size: 3rem;
}
#back {
overflow: auto;
font-size: 8rem;
}
p {
margin: 0;
padding: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class ="scroll" id="back">
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Autem, quam similique quibusdam libero voluptatum laboriosam, sunt possimus non nobis recusandae, excepturi ex voluptates! Neque veniam, sapiente magnam fuga unde autem.
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Fugiat consequatur consectetur laudantium voluptatibus, iusto molestiae fugit inventore rerum, sit sed dolor ratione perferendis beatae molestias. Asperiores odio mollitia quisquam voluptates.</p>
</div>
<div class ="scroll" id="front">
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Autem, quam similique quibusdam libero voluptatum laboriosam, sunt possimus non nobis recusandae, excepturi ex voluptates! Neque veniam, sapiente magnam fuga unde autem.
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Fugiat consequatur consectetur laudantium voluptatibus, iusto molestiae fugit inventore rerum, sit sed dolor ratione perferendis beatae molestias. Asperiores odio mollitia quisquam voluptates.</p>
</div>
EDIT
What is below is not an answer to the question, which is now more specific about a FF behavior more than a scroll sync between the two divs.
For scroll sync
That is more about some maths... And also which values to use.
You have to calculated a percentage of what has been scrolled from what is scrollable. Here is the key! What is scrollable is not the whole height of the element because there is always a part that is visible.
That make three values to consider about #back:
A: the visible part of the div, which you get using .innerHeight()
B: the amount of scrolled pixels, which you get with .scrollTop()
C: the full height of the div, including the parts already scrolled (above the top) and the one to be scrolled (below the bottom). That is the scrollHeight property.
So to obtain the right percentage, the formula is: B/(C-A).
Then, use this percentage on the #front "scrollable pixels", which again, is the full height minus the visible height.
And there you go!
let back_innerHeight = $("#back").height()
let back_scrollHeight = document.querySelector("#back").scrollHeight
let front_innerHeight = $("#front").innerHeight()
let front_scrollHeight = $("#front")[0].scrollHeight
$("#back").on("scroll", function () {
// Get how many pixels were scrolled on #back
let back_scrolled = $(this).scrollTop()
// Calculate the scrolled percentage
let percentage_back = back_scrolled / (back_scrollHeight - back_innerHeight)
// Calculate how many pixels to scroll on #front
let scrollIT = (percentage_back * (front_scrollHeight - front_innerHeight))
// Just to validate that the percentage is applied correctly...
let percentage_front = scrollIT / (front_scrollHeight - front_innerHeight)
console.log("Scrolled % BACK:", percentage_back, "FRONT:", percentage_front)
// Apply the scroll
$("#front").scrollTop(scrollIT);
});
window.onresize = function(){
back_innerHeight = $("#back").height()
back_scrollHeight = document.querySelector("#back").scrollHeight
front_innerHeight = $("#front").innerHeight()
front_scrollHeight = $("#front")[0].scrollHeight
}
div {
}
#front {
overflow: hidden;
position: fixed;
background-color: black;
color: white;
right: 0;
left: 0;
bottom: 0;
top: 0;
margin: auto auto auto auto;
width: 25%;
height: 35%;
font-size: 3rem;
}
#back {
height: 95vh;
overflow: auto;
overflow-x: hidden;
overflow-y: auto;
font-size: 8rem;
}
p{
margin:0;
padding:0;
}
/* Just for this demo here... to limit the SO console's height */
.as-console-wrapper{
height: 1.4em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="back">
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Autem, quam similique quibusdam libero voluptatum laboriosam, sunt possimus non nobis recusandae, excepturi ex voluptates! Neque veniam, sapiente magnam fuga unde autem.
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Fugiat consequatur consectetur laudantium voluptatibus, iusto molestiae fugit inventore rerum, sit sed dolor ratione perferendis beatae molestias. Asperiores odio mollitia quisquam voluptates.</p>
</div>
<div id="front">
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Autem, quam similique quibusdam libero voluptatum laboriosam, sunt possimus non nobis recusandae, excepturi ex voluptates! Neque veniam, sapiente magnam fuga unde autem.
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Fugiat consequatur consectetur laudantium voluptatibus, iusto molestiae fugit inventore rerum, sit sed dolor ratione perferendis beatae molestias. Asperiores odio mollitia quisquam voluptates.</p>
</div>
Some documentation:
.innerHeight()
.scrollHeight

How to detect a div box on scroll

I want to positioned a div box fixed every time I scroll down the page as touch that box and keep scrolling down so that it never disappears after a user sees it.
$(window).scroll(function() {
if($('section#top_casino_offer').scrollTop() +
$('section#top_casino_offer').innerHeight() >= $('section#top_casino_offer')[0].scrollHeight) {
console.log('show');
} else {
console.log('hide');
}
});
I made a quick snippet for it here
I tried the code above but it does not work.
you could specify a scrolling value like this, Check the following snippet :
$(window).scroll(function() {
var y_scroll_pos = window.pageYOffset;
var scroll_pos_test = 90;
// set to whatever you want it to be
if(y_scroll_pos > scroll_pos_test) {
$("#top_casino_offer").css("position","fixed");
}
else
{
$("#top_casino_offer").css("position","relative");
}
});
.outer{
height: 1100px;
background: green;
width: 100%;
}
#yellow{background: yellow;
}
#top_casino_offer {
top: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="outer">
<p>Paragraph</p>
<section id="yellow">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aut doloremque repellendus eligendi, dolorem vel sapiente harum repellat voluptatum hic, officiis perspiciatis dolor labore maiores cumque eos necessitatibus non ex, fuga.</p>
</section>
<section id="top_casino_offer">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aut doloremque repellendus eligendi, dolorem vel sapiente harum repellat voluptatum hic, officiis perspiciatis dolor labore maiores cumque eos necessitatibus non ex, fuga.</p>
</section>
</div>
hope this helps :)

CSS Change Background Color at Certain Point

I would like the background of the entire site to change from white to black when a certain element comes into view. So when you scroll by the element the background transitions to black. When you scroll back up I want the background color of the page to change back to white. Thank you!
HTML:
<div id="#block-yui_3_17_2_2_1495044195108_28541" class="colorChange">
<script>
$(window).scroll(function () {
$('#block-yui_3_17_2_2_1495044195108_28541').each(function () {
var topOfWindow = $(window).scrollTop(),
bottomOfWindow = topOfWindow + $(window).height();
var imagePos = $(this).offset().top;
if(imagePos <= bottomOfWindow-100 && imagePos >= topOfWindow-250){
$(this).addClass('colorChange');
}else{
$(this).removeClass('colorChange');
}
});
});
</script>
CSS:
.colorChange{
#siteWrapper {
-webkit-animation-name: colorChange;
-webkit-animation-duration: 1s;
-webkit-animation-timing-function: ease-in;
animation-name: colorChange;
animation-duration: 1s;
animation-timing-function: ease-in;
}}
#-webkit-keyframes colorChange {
0% {
background-color:black;
}
100.0% {
background-color:black;
}
}
#keyframes colorChange {
0% {
background-color:black;
}
100.0% {
background-color:black;
}
}
Using the scroll event you can calculate the offset of the h1 (or whatever element) which gets the current coordinates of the element. the wScroll variable gets the current vertical position of the scroll bar in this case the top of the window. On the condition you check if the scrollbar is greater or equal to the element you which to target and subtract that from the window height (if you wish to change the background once the element is on the screen change the 1.2 to 1) add a transition to the body for the animation. Check the demo scroll down.
Sorry if its not well explained, excuse my writing.
$(window).scroll(function(){
var wScroll = $(this).scrollTop();
if(wScroll >= $('h1').offset().top - ($(window).height() / 1.2 ) ){
$("body").css("background-color", "black");
}else{
$("body").css("background-color", "white");
}
});
body{
transition: background-color 0.3s ease-in-out;
}
p{height: 1000px;}
h1{
height: 400px;
color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="hei">
<p> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Fugit autem reprehenderit, nesciunt maxime incidunt facilis, aliquid vel deserunt, provident voluptatibus magni, nam. Doloribus sint ipsa nihil fuga, ad minima reiciendis.Lorem ipsum dolor sit amet, consectetur adipisicing elit. Fugit autem reprehenderit, nesciunt maxime incidunt facilis, aliquid vel deserunt, provident voluptatibus magni, nam. Doloribus sint ipsa nihil fuga, ad minima reiciendis. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Fugit autem reprehenderit, nesciunt maxime incidunt facilis, aliquid vel deserunt, provident voluptatibus magni, nam. Doloribus sint ipsa nihil fuga, ad minima reiciendis. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Fugit autem reprehenderit, nesciunt maxime incidunt facilis, aliquid vel deserunt, provident voluptatibus magni, nam. Doloribus sint ipsa nihil fuga, ad minima reiciendis. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Fugit autem reprehenderit, nesciunt maxime incidunt facilis, aliquid vel deserunt, provident voluptatibus magni, nam. Doloribus sint ipsa nihil fuga, ad minima reiciendis. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Fugit autem reprehenderit, nesciunt maxime incidunt facilis, aliquid vel deserunt, provident voluptatibus magni, nam. Doloribus sint ipsa nihil fuga, ad minima reiciendis. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Fugit autem reprehenderit, nesciunt maxime incidunt facilis, aliquid vel deserunt, provident voluptatibus magni, nam. Doloribus sint ipsa nihil fuga, ad minima reiciendis. </p>
<h1>Change to Black</h1>
</div>
Your $(window).scroll is correct but i think your code lacks the proper setup to do what you want. Here is a working sample i made from your code to change the color of the background when the block div comes into view when scrolling.
https://codepen.io/Nasir_T/pen/jmvwEP
Hope this helps.
If you only want something to happen when the element is in the viewport, you can find the top/bottom positions of the element and compare it to the scrolled distance and bottom of the window.
$(window).on('resize scroll',function() {
var $div = $('div'),
$body = $('body'),
st = $(this).scrollTop(),
wh = $(this).height(),
wb = st + wh,
dh = $div.height(),
dt = $div.offset().top,
db = dh + dt;
if (dt < wb && db > st) {
$body.addClass('color');
} else {
$body.removeClass('color');
}
})
section {
height: 150vh;
}
div {
background: black;
height: 200px;
}
.color {
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section></section>
<div></div>
<section></section>
I assume your real issue are the first to lines in your CSS which is not valid. Have a look at the reference. If you want to select all .colorChange inside of #pageWrapper use:
#siteWrapper .colorChange {}
Also remove the "#" in your HTML like so:
<div id="block-yui_3_17_2_2_1495044195108_28541" class="colorChange">
I also would recommend you two throttle your events, so that you do not listen to every scroll event, which could dramatically slow down your system, but every 50 seconds or so. Have a look at ScrollSpy or some jquery throtte plugin.

Hardcode element position in CSS for non-JavaScript-users

I have a HTML-Document which is structured as shown in the following figure:
The red blocks which represent the text of the sidenotes are placed relatively to the footnote numbers in the text using CSS. If the text has many sidenotes and/or the texts of the sidenotes are long, the sidenotes overlap. To prevent such a behaviour I am using JavaScript to set the top margin of these elements in order to shift them downwards.
To prevent that the website is not usable without JavaScript enabled, I would like to hardcode the top margin value of the elements that need shifting down in the CSS-file. To take into account the different screen resolutions, I thought of using the CSS #media-query to set different top margins for other screen resolutions.
Example:
#media(min-width: 80em) {
.container { width: 40em; }
#sidenote-45 { margin-top: 15px; }
[...]
}
#media(min-width: 60em) {
.container { width: 30em; }
#sidenote-56 { margin-top: 28px; }
#sidenote-89 { margin-top: 12px; }
[...]
}
[maybe more #media-queries for other screen sizes]
What do you think about this approach?
You can use absolute position relative to the container to place the notes at the left or right of the div and if you don't set top property the box maintains in its position aligned with the number. Something like this:
.container {
border: solid 2px black;
background: white;
width: 30%;
margin: 20px auto;
position: relative;
}
sup {
color: red;
}
.notes {
position: absolute;
left: -220px;
color: black;
display: block;
background: #8ac88a;
width: 200px;
font-size: 14px;
padding: 5px;
margin-top: -10px;
}
.right {
left: auto;
right: -220px;
}
<div class="container">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. In dolorum voluptate provident doloremque aperiam laboriosam ea, vel nihil illum, beatae nemo mollitia possimus, velit<sup>1<span class="notes">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus, et!</span></sup> sapiente nobis! Expedita possimus incidunt nam laudantium corrupti eaque, eveniet fuga perferendis, enim praesentium vero voluptatibus adipisci, dicta blanditiis aliquid asperiores accusantium. Provident voluptate explicabo necessitatibus eos sequi
modi non in nesciunt, debitis alias architecto doloremque sed<sup>2<span class="notes right">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus, et!</span></sup> quam voluptatem aut dolorem officia ipsa eum dicta optio delectus ullam
aliquam! Dicta rerum praesentium, laudantium suscipit earum, voluptates placeat totam aperiam non atque consequatur cupiditate neque! Reiciendis consectetur quo, alias facilis officia totam illo minus? Vitae distinctio culpa nesciunt voluptate tempore!
Error enim aperiam odio debitis culpa excepturi, minus molestias inventore amet recusandae<sup>3<span class="notes">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus, et!</span></sup> fugit sit quasi qui ipsum. Aperiam quaerat tenetur,
voluptatibus eaque. Voluptatum veniam, nihil accusamus nesciunt nobis dolore cumque amet asperiores qui, ducimus iusto voluptatibus.

Dynamically and completely fill a div with placeholder text in javascript

I would like to Fill a div with placeholder text.
I have a div that is 100% width+height. Due to many form factors this height and width will be changing based on the users resolution. How can i dynamically fill that div with lorem ipsum. Also how would i recalculate if window sizes changes? I know i could manually do this with copy paste and overflow hidden but I would rather achieve this in javascript
JSFiddle
css
html,body {
/*background:#edecec;*/
height: 100%;
}
.block-text{
text-align: justify;
font-size: 8px;
font-color: rgba(88,89,91, 1);
font-family: georgia;
line-height: 7px;
}
html
<div class="block-text">
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore, eius, ab, molestiae praesentium hic quia quaerat culpa quas consectetur dolor veritatis vel voluptas minus laborum minima quis dolorum necessitatibus tempora.
</p>
</div>
http://jsfiddle.net/h54tP/1/
var bool = true;
var maxHeight = $('.block-text').height();
do {
$('.container').append("<p> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore, eius, ab, molestiae praesentium hic quia quaerat culpa quas consectetur dolor veritatis vel voluptas minus laborum minima quis dolorum necessitatibus tempora. </p>");
if ($('.container').height() > maxHeight) bool = false;
} while (bool);
Here, as described in my comment. One wrapping element insinde your text box, the block-text set to 100% height and a small while loop do the trick.
Small note: This will not do anything when the window is resized. For that, however, you could just call that entire code inside a window-size-change function.
Also, this allows the text to be slightly larger than the screen. If you want it slightly smaller instead, just do
$('.container').children().last().hide();
in the "if"-clause.
I realize you wanted to solve this with javascript, but have you considered using css psuedo-elements with content? If this is just for placeholder text as you develop I think it will do what you want without having to add a bunch of javascript and fiddle with resize events.
.block-text>p:after {
content: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore, eius, ab, molestiae praesentium hic quia quaerat culpa quas consectetur dolor veritatis vel voluptas minus laborum minima quis dolorum necessitatibus tempora.';
}

Categories

Resources