There are a lot of posts on this site that I have read but nothing is working for me and I'm not sure why.
I'm trying to make a menu that "sticks" to the top of the page as you scroll past it and vice versa (stops sticking when you scroll back up)
Javascript
$(document).ready(function(){
var top = $('#FloatingMenu').offset().top - parseFloat($('#FloatingMenu').css('marginTop').replace(/auto/,100))
document.addEventListener("scroll",Scroll,false);
document.addEventListener("gesturechange",Scroll,false);
function Scroll() {
var y = $(this).scrollTop();
if (y >= top) {
$('#FloatingMenu').addClass('fixed');
} else {
$('#FloatingMenu').removeClass('fixed');
}
CSS
#FloatingMenu.fixed {
position: fixed;
top: 0;
left: 0;
z-index: 1;
width: 100%;
background-color: black;
color: red;
}
#FloatingMenu {
background-color: red;
color: black;
width: 100%;
text-align: center;
}
I've tried doing repainting, i've tried stopping the "inertia" scrolling (which I can't get to stop on Chrome on iOS) Either way, everything I've tried has the same results. Works perfectly in a PC or on a Android, but on an iPhone, the menu will not repaint and be "stuck" at the top until the scrolling stops AND the finger is removed from the screen.
Is there a fix for this? Everything I'm reading suggests that there is but notn a single solution has changed anything for me.
The strange thing is, if your scrolling back up (the menu is already stuck at the top) and you scroll past it, it auto un-sticks (even while scrolling) and works fine.
The only time its a problem is when its "repainting" the "fixed" menu.
I hope there is a solution. Everything suggests that after iOS 8 it was fixed (and i'm testing on 10+) but It wont show the menu while scrolling until you stop and let go. Tested on an iPhone 6 and and iPad Air 2. safari and chrome, same results across the board.
I think I solved this question.
It's pretty funny.
Just add to style transform
transform: scaleX(1);
Or
transform: translateX(0);
And it's all
.fixedSidebar{
position: fixed;
right:0;
border:1px solid gray;
height:100vh;
width:17%;
max-width:70px;
transform: scaleX(1);
}
The problem is with position:fixed. This seems to have known issues with safari specifically on mobile devices. After doing some searches for hours, I believe that I may have been able to fix this issue.
The solution I used is to use position:-webkit-sticky for iOS safari and use position:sticky for desktop browsers. More documentation on this property can be found here :
http://caniuse.com/#feat=css-sticky
Can you please try the following code:
CSS:
#FloatingMenu.fixed {
top: 0;
left: 0;
z-index: 1;
width: 100%;
background-color: black;
color: white;
}
#FloatingMenu {
position: -webkit-sticky;
position: sticky;
background-color: lightgray;
color: black;
width: 100%;
height: 60px;
text-align: center;
padding-top: 18px;
font-weight: 800;
}
JS :
$(document).ready(function(){
var top = $('#FloatingMenu').offset().top - parseFloat($('#FloatingMenu').css('marginTop').replace(/auto/,100));
window.addEventListener('scroll',Scroll,false);
function Scroll() {
var y = $(this).scrollTop();
if (y > top) {
$('#FloatingMenu').addClass('fixed');
} else if (y<=top) {
$('#FloatingMenu').removeClass('fixed');
}
}
});
Please note that I have removed the fixed property completely and applied the sticky property to the #FloatingMenu selector itself. Seems to work for me on my iOS simulator safari, and iPhone 6 Safari and on Chrome & Safari in my desktop.
A simple working example of this fix can be found here : Link
Hope this helps. Cheers.
You shouldn't add any event listener for scrolling because it can produce several errors - maybe crashing your browser. This is the first thing you need to change:
JS:
$(document).ready(function(){
var top = $('#FloatingMenu').offset().top - parseFloat($('#FloatingMenu').css('marginTop').replace(/auto/,100));
function Scroll() {
var y = $(this).scrollTop();
if (y >= top) {
$('#FloatingMenu').addClass('fixed');
} else {
$('#FloatingMenu').removeClass('fixed');
}
setInterval(function() {
Scroll();
}, 120);
});
The second thing you need to fix is your "function Scroll". It's right: just a function maded to be called by a DOM element. But what if your event isn't triggered by a DOM element? Maybe that's your problem!
So you can even try adding Event Listener for scrolling just fixing that, but I don't recommend.
JS
function Scroll() {
var y = $('body').scrollTop();
if (y >= top) {
$('#FloatingMenu').addClass('fixed');
} else {
$('#FloatingMenu').removeClass('fixed');
}
PAY ATENTION:
If the first scrollable parent of #FloatingMenu isn't the <body>, you should fix that $('body').
Related
I work in a web development environment that uses WordPress. The theme we use is ThemeCo's Pro.
I'm still learning javascript (so please forgive me if I'm really far off), and I'm trying to use jQuery to write a piece of code that will allow an element to appear after scrolling 1vh of the page. Can anyone help me understand why this isn't working? I can't tell if it's my code, or my theme might not be allowing it. The theme itself uses jQuery on the front end, but has a javascript file I may edit, but for the most part, the frontend editor is pretty reliable for code.
I'm using pieces from this question to help me write it, as well as referencing the jQuery library.
$(window).scroll(function() {
var scroll = $(window).scrollTop();
var minH = $(window).height() * 1;
if (scroll >= minH) {
$("#circle-menu").fadeTo(500, 1);
}
else {
$("#circle-menu").fadeTo(500, 0);
}
});
Just to make sure I understand what you're trying to do, I'll quickly reiterate what your code does: Basically, minH is supposed to be 1vh, and if scroll is >= minH, you want #circle-menu to fade in.
That being said, I think we have to look at a couple potential issues with the code above:
1vh is really just 1/100 of the viewport height, which can be calculated as:
// this is 1vh, which is what you're going for
$(window).height() / 100
As opposed to:
// this is 100vh
$(window).height() * 1
The second would be that you're using fadeTo. The difference between fadeIn/fadeOut and fadeTo is that fadeTo doesn't affect an element's display property. It only affects an element's opacity property. This means that if the theme's default value for the menu's display property is set to "none", fadeTo is not going to make it fade into sight. To get around this, in my opinion, it would be better to use fadeIn and fadeOut instead, especially since it doesn't seem like you're trying to control different levels of opacity (which is what fadeTo is really needed for).
I made a quick code snippet to demonstrate the above fixes.
$(window).scroll(function() {
var scroll = $(window).scrollTop();
var vh = $(window).height() / 100;
var minH = vh;
if (scroll >= minH) {
$("#circle-menu").fadeIn(500);
}
else {
$("#circle-menu").fadeOut(500);
}
});
p {
margin-top: 10vh;
height: 150vh;
border: 2px solid #666;
}
#circle-menu {
font-family: 'Segoe UI', verdana, sans-serif;
font-size: 20px;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 50px;
box-shadow: 1px 2px 3px rgba(50,50,50,0.1);
z-index: 1;
display: none;
background-color: steelblue;
color: white;
padding-left: 20px;
padding-top: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="circle-menu">Menu</div>
<p></p>
Having a small problem. (Refer to fiddle)
I've got a container in my project that has been rotated 180 deg, with a container inside that has been rotated another 180 back to the original state.
I need to invert the scroll.
How would i go about this?
Dont mind wasting your time with a method, that reverts the basic setup.
The basic setup has to stay.
http://jsfiddle.net/vavxy36s/
Description of fiddle:
"Start" marks the initial string and "end" ofcourse the last one.
If you try scrolling you will realize, that it's inverted as to how one would normally scroll.
.class1 {
height: 200px;
background-color: blue;
color: white;
width: 100px;
overflow-y: scroll;
overflow-x: hidden;
direction: rtl;
-webkit-transform: rotate(180deg);
}
.class2 {
direction: ltr;
-webkit-transform: rotate(180deg);
}
EDIT: Just mousewheel scroll, has to be inverted.
Edit: Your original setup has different behaviors in Chrome and in [IE & Firefox]. In Chrome, the scroll is already inverted, but in FF and IE, the scroll remains normal. My solution reverts it in both cases, but the behaviors remain different across browsers.
You could add these styles:
/* ...
Your original styles
...
*/
.class1 {
overflow: hidden;
position: relative;
}
.class2 {
position: absolute;
bottom: 0;
}
And then, using jQuery, modify the bottom CSS property of .class2:
var scrollPos = 0,
diff = $('.class2').height() - $('.class1').height();
$('.class1').on('mousewheel', function(e) {
scrollPos = Math.min(
0,
Math.max(
-diff,
scrollPos + e.originalEvent.wheelDelta
)
);
$('.class2').css('bottom', scrollPos);
});
JS Fiddle Demo
You could use the mousewheel library to catch and invert the scroll movement.
$(".class1").mousewheel(function(event) {
event.preventDefault();
this.scrollTop -= (event.deltaY * event.deltaFactor * -1);
});
You can view a demo here: http://jsfiddle.net/fduu20df/1/
I've found this JS fiddle, which does exactly what I'm looking for. However, I can't seem to figure out how to get it to work when I move the navigation to the side.
var hoverMenu = $('#HiddenMenu'),
hoverSpace = $('#HoverSpace');
hoverSpace.on('mousemove', function(event) {
if(35 - event.clientY < 0) {
hoverMenu.css({top: 35 - event.clientY});
} else {
hoverMenu.css({top: 0});
}
}).on('mouseout', function() {
hoverMenu.css({top: -35});
});
http://jsfiddle.net/PaZHH/1/ <-- this is working example of the clientX/Y event I'm wanting
I can't seem to implement this by using clientX & moving the navigation to the right hand side.
This is where I managed to get too http://jsfiddle.net/PaZHH/102/
Make this changes.
Add absolute positioning to hidden menu:
#HiddenMenu {
background-color: #e00;
position: absolute;
right: -35px;
}
Make the hover space position relative:
#HoverSpace {
position: relative;
background-color: #aeaeae;
overflow: hidden;
width: 45px;
height: 500px;
}
Now, you'll be fine. You can check the result here. It currently works by moving in from right, which is a bit different from you horizontal sample.
I have a web page where I want to use the full height (no more, no less) of the screen with two stacked divs, so that the second div fills out the height that remains after the first one.
At the moment I am doing it like this:
css
body { height: 100%; }
JavaScript
window.onload=function(){
document.getElementById('div2').style.height =
(document.getElementById('body').offsetHeight -
document.getElementById('div1').offsetHeight) + 'px';
}
This works fine, but in mobile browsers (tested on Android default browser and Chrome) the address bar remains visible, although it can be hidden and the space used for the second div. I assume similar behaviour can be expected from iPhones.
So my question is: Does anyone know how to get the available height in a mobile browser, including retractable address bar?
edit
Ifound this:http://mobile.tutsplus.com/tutorials/mobile-web-apps/remove-address-bar/, but I can't get it to work in Chrome.
update
I am now using this code, but it still doesn't work in Android Chrome (and I haven't tried it in iPhones).
JavaScript function:
if(typeof window.orientation !== 'undefined') {
document.body.style.height = (window.outerHeight) + 'px';
setTimeout( function(){ window.scrollTo(0, 50); }, 50);
}
document.getElementById('div2').style.height =
(document.body.offsetHeight -
document.getElementById('div2').offsetHeight) + 'px';
I am calling this function in window.onload and window.onresize.
Try this:
HTML
<div class="box">
<div class="div1">1st</div>
<div class="div2">2nd</div>
<div class="clear"></div>
</div>
CSS
html, body { height: 100%; }
div.box { background: #EEE; height: 100%; width: 600px; }
div.div1{background: #999; height: 20%;}
div.div2{ background: #666; height: 100%; }
div.clear { clear: both; height: 1px; overflow: hidden; font-size:0pt; margin-top: -1px; }
See the demo.
Hope it helped.
In Chrome for Mac, one can "overscroll" a page (for lack of a better word), as shown in the screenshot below, to see "what's behind", similar to the iPad or iPhone.
I've noticed that some pages have it disabled, like gmail and the "new tab" page.
How can I disable "overscrolling"? Are there other ways in which I can control "overscrolling"?
The accepted solution was not working for me. The only way I got it working while still being able to scroll is:
html {
overflow: hidden;
height: 100%;
}
body {
height: 100%;
overflow: auto;
}
In Chrome 63+, Firefox 59+ and Opera 50+ you can do this in CSS:
body {
overscroll-behavior-y: none;
}
This disables the rubberbanding effect on iOS shown in the screenshot of the question. It however also disables pull-to-refresh, glow effects and scroll chaining.
You can however elect to implement your own effect or functionality upon over-scrolling. If you for instance want to blur the page and add a neat animation:
<style>
body.refreshing #inbox {
filter: blur(1px);
touch-action: none; /* prevent scrolling */
}
body.refreshing .refresher {
transform: translate3d(0,150%,0) scale(1);
z-index: 1;
}
.refresher {
--refresh-width: 55px;
pointer-events: none;
width: var(--refresh-width);
height: var(--refresh-width);
border-radius: 50%;
position: absolute;
transition: all 300ms cubic-bezier(0,0,0.2,1);
will-change: transform, opacity;
...
}
</style>
<div class="refresher">
<div class="loading-bar"></div>
<div class="loading-bar"></div>
<div class="loading-bar"></div>
<div class="loading-bar"></div>
</div>
<section id="inbox"><!-- msgs --></section>
<script>
let _startY;
const inbox = document.querySelector('#inbox');
inbox.addEventListener('touchstart', e => {
_startY = e.touches[0].pageY;
}, {passive: true});
inbox.addEventListener('touchmove', e => {
const y = e.touches[0].pageY;
// Activate custom pull-to-refresh effects when at the top of the container
// and user is scrolling up.
if (document.scrollingElement.scrollTop === 0 && y > _startY &&
!document.body.classList.contains('refreshing')) {
// refresh inbox.
}
}, {passive: true});
</script>
Browser Support
As of this writing Chrome 63+, Firefox 59+ and Opera 50+ support it. Edge publically supported it while Safari is an unknown. Track progress here and current browser compatibility at MDN documentation
More information
Chrome 63 release video
Chrome 63 release post - contains links and details to everything I wrote above.
overscroll-behavior CSS spec
MDN documentation
One way you can prevent this, is using the following CSS:
html, body {
width: 100%;
height: 100%;
overflow: hidden;
}
body > div {
height: 100%;
overflow: scroll;
-webkit-overflow-scrolling: touch;
}
This way the body has never any overflow and won't "bounce" when scrolling at the top and bottom of the page. The container will perfectly scroll its content within. This works in Safari and in Chrome.
Edit
Why the extra <div>-element as a wrapper could be useful: Florian Feldhaus' solution uses slightly less code and works fine too. However, it can have a little quirk, when it comes to content that exceeds the viewport width. In this case the scrollbar at the bottom of the window is moved out of the viewport half way and is hard to recognize/reach. This can be avoided using body { margin: 0; } if suitable. In situation where you can't add this CSS the wrapper element is useful as the scrollbar is always fully visible.
Find a screenshot below:
You can use this code to remove touchmove predefined action:
document.body.addEventListener('touchmove', function(event) {
console.log(event.source);
//if (event.source == document.body)
event.preventDefault();
}, false);
Try this way
body {
height: 100vh;
background-size: cover;
overflow: hidden;
}
html,body {
width: 100%;
height: 100%;
}
body {
position: fixed;
overflow: hidden;
}
position: absolute works for me. I've tested on Chrome 50.0.2661.75 (64-bit) and OSX.
body {
overflow: hidden;
}
// position is important
#element {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
overflow: auto;
}
Bounce effect cannot be disabled except the height of webpage equals to window.innerHeight, you can let your sub-elements scroll.
html {
overflow: hidden;
}