This is a strange bug i'm facing, i don't really understand the problem so forgive me for the obscure title.
The problem is I'm developing a SPA style site and i want the content to slide in from the right (when the buttons at the bottom are clicked)
I thought this would be easy, but for some reason it is easy to achieve from the left, using the example below
.page {
right: 100%;}
.page.active {
right: 0; }
https://jsfiddle.net/pphfstos/3/
and less ideally to slide the full width across like this
.page {
left: -100%;}
.page.active {
left: 0; }
https://jsfiddle.net/pphfstos/4/
But when i try to create the same effect as the first example but from the right it not only doesn't work but totally seems to destroy the page
.page {
right: -100%;}
.page.active {
right: 0; }
https://jsfiddle.net/pphfstos/5/
There is other code involved as you can see in the fiddle, but these are the only things that are different between the 3 examples
Can anyone explain what is happening and how to fix it?
Content you position outside of the viewport to the left is actually hidden, and can’t be reached via scrolling.
Content you position outside of the viewport to the right however “extends” the page in that direction, and can be scrolled to.
Remove the overflow-x: hidden from html/body in your first and third fiddle, and you see what I mean – in the first one, the content positioned to the left is hidden, and no scrollbar appears; in your third fiddle however you do get a scrollbar, and the content positioned to the right can be reached via scrolling, moving the part of your page that is initially visible to the left while you’re doing so.
Now, setting overflow-x: hidden removes the ability to scroll using the mouse; but the viewport can still be “shifted” to display that content, for example by navigating to an anchor – and that is what your links are doing. (But because this is an “instant jump” and not smooth scrolling, you don’t see your initially visible content move away, it is just gone instantly.)
So you simply need to suppress the default action of your anchor links in your click event handler:
mainNavButton.click(function (e) {
e.preventDefault(); // prevent event default action
// … rest of your code
– and the effect of the page ”jumping” to the anchor position is gone.
https://jsfiddle.net/pphfstos/6/
Related
I am using a div that slides out when you click on it.
Here are some images of what I am trying to achieve:
This is the Div, collapsed by default
This is the Div after it is slid out (highlighted)
This is what happens after screen size is changed. The clickable div is present behind content Which I wish to avoid.
My Div's CSS:
.sliderDiv {
z-index: -10;
position: relative;
left: 200px;
width: 240px;
}
I use this command to slide it out on click:
slideItOut:function(){
var divsize=$(".sliderDiv").offset().left-150;
if(divsize>100){
$(".sliderDiv").animate({
"left":"-=194px"
},"slow");
}
else{
$(".sliderDiv").animate({
"left":"+=194px"
},"slow");
}
}
The problem is when you resize, it is not responsive at all and the div actually hides behind other content. Maybe this method is not supposed to be responsive.
Is there a way to make the same "slider" responsive or atleast hold its position while the screen size is changed?
I want to know of any way in which I could resize my window or screen and the div remains in same area as the 1st two images.
Also, this is being implemented in a modal. So its not exactly in a fixed area of the screen.
It won't solve without your full source code, I think. You should give its source code or put somewhere. Then, I try to fix. Or, I can offer optimum way
I've created a hidden sidebar navigation menu which, when made visible - moves the site-wrap (main content of the page) to the right to expose the menu:
.nav-trigger:checked + label, .nav-trigger:checked ~ .site-wrap {
left: 16.5em;
}
This all works as I would hope, but the problem is one that arises on mobile, when the user begins trying to swipe around the page. If you touch the left edge of the site wrap and drag it to the left, it scrolls the page in that direction - as if it was dragging the site wrap back across the navigation element behind it.
I have tried adding two variations of overflow hidden to body, but this has no effect:
body{
background: #bodyColor;
color: #headerColor;
font-family: #openSans;
font-size: 16px;
overflow-x: hidden;
overflow: hidden;
}
I did add the following jquery which prevented touch gestures entirely:
var touchDisabled = false;
$("#nav-trigger").click(function(){
if( touchDisabled == false ){
$(document).bind('touchmove', function(e) {
e.preventDefault();
});
touchDisabled = true;
}else{
$(document).unbind('touchmove');
touchDisabled = false;
}
});
but this is not the ideal situation as I'd like to retain vertical scroll if possible, and prevent horizontal scroll/swipe/drag/whatever-you-want-to-call-it.
Part of the reason I'm struggling to solve this is because I'm not entirely sure what to search for, it doesn't seem to be a scroll in the traditional sense, more dragging the div around the page.
The link to demonstrate the problem is:
http://streeten-new.streeten.co.uk/
(obviously only recreatable on mobile). I hope this helps to illustrate the problem as it's not the easiest of things for me to explain in words.
* 12/08 update *
Still having this problem unfortunately.
The problem also manifests itself in both the site-wrap and the .navigation scrolling at the same time as you swipe up on mobile. I would like to be able to tell site-wrap to just stay in place and don't move an inch, no matter how you swipe, and just allow vertical scroll/swipe in the navigation menu.
I've made it so that when you open the menu, overflow: hidden is being added to body and overflow: auto is being added to the navigation. This works perfectly on desktop! When you scroll, only the nav moves and the body is completely frozen. But on mobile it seems to have absolutely no effect.
$("#hamburger").click(toggleMenu);
var menuOpen = false;
function toggleMenu(){
$(".site-wrap, header").toggleClass("slideRight");
$(".navCover").toggleClass("slideRight");
$("#logo").toggleClass("slideLeft");
$("body, #fouc").toggleClass("preventScroll");
$(".navigation").toggleClass("allowScroll");
window.setTimeout(function(){
$("header button").toggleClass("slideLeft");
}, 250);
if (menuOpen == true){
menuOpen = false;
}else{
menuOpen = true;
}
}
.preventScroll{
overflow: hidden;
}
.allowScroll{
overflow: auto;
}
Any help much appreciated.
I have now (mostly) resolved this. I think the edit I made is another issue which I will raise separately.
For the benefit of others who may read this, in order to prevent the site-wrap container from being "swipeable" for want of a better word - whereby it was possible to drag it around the screen in every direction after it had been repositioned on opening the navigation menu - I had to use overflow: hidden
I had initially tried this, but where I went wrong was applying it to the body, which according to this thread doesn't work on mobile:
Overflow-x:hidden doesn't prevent content from overflowing in mobile browsers
I added another div within body, containing all my content and applied overflow: hidden to both body and this new div (belt and braces), which then resolved the issue.
Now when the site-wrap has been shifted to the right after clicking the hamburger icon, it is impossible to drag/swipe it around the screen on mobile.
I'm using angularjs to develop a web application. I have several nested div. Each of them correspond to an item that the user can select.
A good example of my div display is in the official angularJs documentation :
http://plnkr.co/edit/qncMfyJpuP2r0VUz0ax8?p=preview
In my code each div have a ng-click="gotoAnchor(x)" event so when I click on a div if it is partially hidden, it pull it up on the page and the user can see all the clicked div.
But I have a header in my page so the first div with an anchor and a click event is not directly at the top of the page. And if I click on the first div, it will scroll and the header won't be visible.
So my question is, is there a way to activate the anchor only if the div isn't fully displayed on the screen ?
If you have an other solution than anchors, I take it.
Thank you in advance.
If I understand your question correctly the issue is that when using $anchorScroll your header is either
a: Being covered up by the div scrolled into frame,
or
b Partially covering up the div that is scrolled into frame.
Either way there are two solutions you should review:
First
make sure you're employing CSS to properly layer your elements, your header (if fixed) should have a z-index that supersedes your divs.
.header { position: fixed; top:0; width: 100%; z-index: 99}
.content { position: relative; margin-top: 10px; z-index: 1;}
REMEMBER Z-index only works on positional elements (See ref)
Second
Employ $anchorScroll.yOffset to make sure your scroll distance is bumped down to compensate for the header height. As seen in the Angular docs, you can use this method in your application:
.run(['$anchorScroll', function($anchorScroll) {
$anchorScroll.yOffset = 50; // always scroll by 50 extra pixels
}])
Update 50 to be the pixel height of your header.
Regarding visibility
There are a few great libraries and directives for checking the visibility of an element - try https://github.com/thenikso/angular-inview as you can specify whether you want to enable an action when only the top, bottom or none of the div is visible.
Note Posistioning the first div correctly on the page will prevent any scroll from being necessary as seen in this plunkr.
I'm building an app with Phonegap and I have a header which I have fixed to the top of viewport.
header {
position: fixed;
top: 0;
width: 100%;
height: 30px;
background-color: red;
z-index: 100;
}
This works as I want except when I tap a input field and the keyboard slides up. Then the positioning is totally discarded. The header is slided higher up outside the visable view. It returns to its place after closing the keyboard again.
I have read that some mobile browser don't care about positioned fixed and absolute to make sure that a possibly small screen don't get covered with a fixed element. Is this true?
Is there a way around this?
I have tried setting the header to absolute when a input is focused. I read about it here, http://dansajin.com/2012/12/07/fix-position-fixed/. However, it doesn't seem to be working for me.
PhoneGap’s implementation of fixed positioning for iOS is poor when it comes to the virtual keyboard. I’ve tried a number of proposed solutions, including the one you linked to, but none of them worked satisfactorily. Disabling KeyboardShrinksView can cause the input field to get hidden under the keyboard.
I ended up going with this workaround, which simply hides the fixed header when the keyboard slides into view and shows it again after the keyboard slides out of view. I await a more complete fix, but this solution has the benefit of being clean and reliable. The 10 ms delay on show() is enough to prevent the header from momentarily flashing in the wrong place while the keyboard is sliding back down. The 20 ms delay on hide() prevents the header from popping up in the wrong place if the user goes directly from one input field to the next.
$(document).on('focus','input, textarea, select',function() {
setTimeout(function() {
$('header').hide();
},20);
});
$(document).on('blur','input, textarea, select',function() {
setTimeout(function() {
$('header').show();
},10);
});
When I click on a list-item, to go to another page, the current page jumps to the top of the screen before transitioning to the next page.
This problem occured in jQM 1.2, and is still not fixed in the newly released 1.3 version.
Does anybody know how to prevent the scroll-to-top, and remember the scroll position when using the back button?
This annoying behaviour is unacceptable, and breaks the whole app experience.
I'm using it as a webapp, on an iPhone 4S, with iOS 6.1.2.
Before I describe your available solutions you need to understand, this is not an error nor is there a perfect solution. The issue is that to animate the transition to another page the viewport has to be at the top of the page so that the current page and the page transitioning in are vertically lined-up.
If you were half-way down a long list on one page (say 1000px) and the page you are transferring to is only a few hundred pixels tall then the current page would animate off the screen properly but the new page would not be visible as it would be above the viewport.
There are 2 viable solutions:
1. iScroll and its jQuery Mobile derivate iScrollview
iScroll homepage: http://cubiq.org/iscroll-4
iScrollview homepage: https://github.com/watusi/jquery-mobile-iscrollview
iScroll is a javascript that can scroll content in a window within a web browser with very similar behaviour to native scrolling on mobile devices such as iPhone and Android. This means you can scroll a window within the browser using native-like scrollbars and physics.
That is also a solution for our current problem. Because of iScroll implementation pages will occupy 100% of page height, no matter how far listview is scrolled. This is also a reason why on return listview will still stay at a same position.
Of course in case you want to implement this solution you should pick iScrollview implementation. You would still be able to implement iScroll, but it would take you much more time.
2. Silent scroll
Official documentation: http://jquerymobile.com/demos/1.1.0-rc.1/docs/api/methods.html
This jQuery Mobile functionality is also the same reason why we have this problem at the first place. Before a page transition is triggered original page is silently scrolled to the top.
In our case, when listview is selected, its position must be remembered (here you will find solutions of data/parameteres storing during the page transition, just search for the chapter: Data/Parameters manipulation between page transitions) before page is changed. In that case, when we return to the previous page we could use pagebefpreshow event to silently scroll to the bottom before page is shown.
//scroll to Y 100px
$.mobile.silentScroll(100);
And here's a working example of silent scroll: http://jsfiddle.net/Gajotres/5zZzz/
More info
If you want to find out more about this topic take a look at this article, you will also find working examples.
I was able to fix this (for iOS) in the following way:
Add a extra container div for the scrolling part. Usually surrounding the scrolling part of your page. In my case right after the header and before the footer code.
Add the following CSS:
.extracontainer {
width: 100%;
height: 100%;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: 0;
padding: 0;
overflow: auto;
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
}
Some of the CSS might be extra but in my case it was to avoid any issues with some other styles that I have using negative margins, paddings, etc.
Also make sure to have the -webkit-overflow-scrolling: touch; to have smooth scrolling.
I hope this helps.
$( document ).on( "mobileinit", function() {
var silentScroll = $.mobile.silentScroll;
$.mobile.silentScroll = function( ypos ) {
if ( $.type( ypos ) !== "number" ) {
// FIX : prevent auto scroll to top after page load
return;
} else {
silentScroll.apply(this, arguments);
}
}
}
For Jquery Mobile 1.4.5 i fixed that by changing this line in jquery.mobile-1.4.5.min.js:
a.mobile.hideUrlBar&&g.load(a.mobile.silentScroll)
to this:
a.mobile.hideUrlBar
Solution to prevent scrool to top is:
body onload="$.mobile.silentScroll(window.scrollY);"
try to use scrollstart to detect window scroll event in jquery mobile, in case you need :)