Detect the presence of the ie10 metro address bar with javascript - javascript

I have a site that has some call to action buttons in a div that is fixed to the bottom of the screen.
We are currently using a div that is positioned absolutely as follows
<div id="buttonBar">footer code</div>
<style>#buttonBar{ bottom: 0; width: 100%; position: fixed; }</style>
This has worked well in all the browsers except for IE10 in metro (modern) mode.
When a link is clicked the address bar shows and covers the button bar, it then disappears
Other than redesigning the layout of the page, I would like the button bar to sit just above the address bar when it is shown.
Does anyone know a way of detecting whether the address bar is visible using javaScript?

You could try to move the footer above the location-bar, until the location-bar collapses, then drop the footer back down. Here's a potential solution:
1.
Move your footer up 50px (or whatever) if the user is likely on an IE10 touch-enabled browser
if (!!window.navigator.msPointerEnabled) { // sniff for IE10 + touch
$("#buttonBar").css("transform", "translateY(-50px)");
}
2.
Listen for the first interaction with the browser, then collapse the footer with the location-bar.
$("body").on("MSGestureStart MSInertiaStart MSGestureTap MSPointerDown", function () {
$("body").off("MSGestureStart MSInertiaStart MSGestureTap MSPointerDown");
$("#buttonBar").css("transform","translateY(0)");
});
This solution hasn't been 100% reliable, there are clearly some interactions that collapse the location-bar but don't trigger an event. I'm working on a better solution and will update once found, but figured I'd share this to get the ball rolling.

Related

Disable scrolling when pop up open and menu not showing on mobile

thanks for looking into my issue
I am creating a website: http://testgod0312.000webhostapp.com/ , all the css are separate by blocks so that it is easier for you to potentially help me (in assets folder).
when you go to map and click on a button, a pop up shows up, but you can keep on scrolling. The button is only coded in css (no js), everything in the map.css file - any idea how to disable overflow without resorting to js? if using js, what would you do as there is no function capturing the opening / closing of the box?
I have a menu (click top right corner), works fine on laptop but on mobile, it shows only 50% of it. The code is in nav.css; with the responsive at the bottom. Any idea on how to display it all?
thanks in advance!!
fafa
#1 can't be solved without javascript as long as browsers are not supporting css:has(). So the only way is to apply a class or a style="overflow: none;" to the body as soon as a popup gets opened and remove it after it was closed. The very same happens already if the menu is opened/closed.
A very small code snippet would be enough:
window.addEventListener("hashchange",
() => document.body.classList.toggle("popup-open", location.hash.startsWith('#popup'))
);
and CSS
body.popup-open {
overflow: none;
}
About #2 inside the nav.css the values applied before the media query (#media all and (max-width: 767px) {) cause the issue.
The menu__right changes from flex to none on small screens. And menu__left still has the right 50% value applied for bigger screens, So adjusting this value inside the media query to 0% solves it.
.menu__left {
right: 0%;
width: 100%;
}

How avoid horizontal html scrolling when a layer is show

I have a div .layer that darkens the entire page to highlight a modal, but when I trigger the event there is a problem to occupying 100% of the screen, and is that the scroll bar of the original browser is deleted
Is there any fancy way to make the div .layer, when is visible, keep the original bar scroll of the page?
In smartphones / tablet I do not find any problem when shooting the event .layer").show(); but on desktop screens the original scroll bar of browser is eliminated and the whole html document moves to right, taking its place.
What would be the correct way to avoid html to the right?
Thanks in advance!
HTML:
<div class="layer"></div>
<div class="open-modal">Open</div>
<div class="modal">
<div class="close-modal">Close</div>
</div>
CSS:
html {width:100%;min-height:100%;margin:0 auto;top:0;left:0;padding:0}
body {top:0;left:0;margin:0;padding:0;min-height:100%}
.layer {
display:none;
position:fixed;
top:0;
left:0;
width:100%;
min-height:100vh;
background:rgba(0,0,0,.9);
z-index:2
}
.modal {display:none;z-index:1}
SCRIPT:
$(document).ready(function(){
$(".open-modal").click(function(){
$(".modal,.layer").show();
$("body").css("overflow","hidden");
});
$(".close-modal,.layer").click(function(){
$(".close-modal,.layer").hide();
$("body").css("overflow","");
});
});
You need to get rid of your use of "overflow". I've included a link below to the Mozilla Developer Network docs for "overflow", but below is a quick quote explaining what's happening.
"hidden
Content is clipped if necessary to fit the padding box. No scrollbars are provided, and no support for allowing the user to scroll (such as by dragging or using a scroll wheel) is allowed. The content can be scrolled programmatically (for example, by setting the value of a property such as offsetLeft), so the element is still a scroll container."
https://developer.mozilla.org/en-US/docs/Web/CSS/overflow
Also, after one cycle of clicking Open and Close, if you were to click Open again, the word Close won't show up. That's because you're not using the .show() method to show that text upon clicking Open. Updated JavaScript below.
JavaScript:
$(document).ready(function(){
$(".open-modal").click(function(){
$(".modal,.layer,.close-modal").show();
});
$(".close-modal,.layer").click(function(){
$(".close-modal,.layer").hide();
});
});

Fixed/absolute positioning neglected in iOS when focusing on input

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);
});

How to restrict scrolling of a mobile site but allow access to potentially retracted address bar

I have a repo up and running if you're interested in contributing to solutions.
I've run into an interesting problem while constructing a mobile site.
I am setting 'overflow: hidden;' to html/body when a drawer is toggled. This is so the window can't be scrolled, and the drawer - which is scrollable - on reaching it's limits doesn't scroll the page (e.preventDefault(); & e.stopPropagation(); simply don't do the trick).
This all works great. Fantastic if this was a Phonegap app. However - as this is a website, the inconsistent overflow setting creates a usability issue with the browser's 'fullscreen mode'. 'Fullscreen mode' is when the address bar is hidden upon scrolling down the page. When scrolling up the bar will reappear. When toggling the drawer the browser is essentially locked in either 'non fullscreen mode' or 'fullscreen mode'. The latter is the real issue - as users are simply unable to access the address bar - and gives the impression the browser has locked up or something weird.
Any bright ideas as to how (probably with Javascript) a scroll/touchmove could still give the effect of entering/exiting 'fullscreen mode'? I've had a play with the fullscreen API, but that's proper fullscreen, not just the address bar.
here are some screenshots:
site loads, we can see the address bar
site is scrollable as expected, browser enters 'fullscreen mode'
we toggle the drawer to open - the site is now unresponsive (besides the drawer scrolling and any gestures [via AngularJS directives] I've got to hide the drawer)
the drawer toggled when the address bar is visible. Good for usability, but the expected 'fullscreen mode' when using a site doesn't occur (would be nice to have the real estate).
EDIT2: https://medium.com seems to achieve what I'm after.
EDIT3: Some success with a invisible absolute positioned div sitting on top of everything - but that has it's own issues.
Rather than setting overflow: hidden; on body when the drawer is out, how about making the drawer position: fixed; overflow-y: auto;, that way the user can make the choice to scroll the body to get to the address bar or the drawer.
Just out of interest, what does Firefox for Android do in this situation? It might be worth filing a bug with the Chromium team if Firefox doesn't display similar usability problems.
EDIT: I've taken a look at the code at https://github.com/patrickmarabeas/marabeas.io when running in Android Chrome and Android Firefox via their respective ADB-enabled remote debuggers (really good tools!).
I've come to the conclusion that there isn't a nice way to get the address bar to show once it's hidden when body has overflow: hidden on it.
There is however after a hacky way!
Shift the main scrollable area from body to a div, in this case, #content. Then, position: absolute; body and make it fill the viewport plus some extra height when on mobile. Given below is the relevant CSS applied on the mobile browsers:
body {
position: absolute;
top: 0;
bottom: -100px;
left: 0;
right: 0;
}
#content {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow-y: auto;
}
Then, as the browser is looking for body to be doing the scrolling as to whether or not to display the address bar, get the #content scroll to be linked with the main body scroll, though this may not be having an effect!:
var lastScrollTop = 0;
document.getElementById('content').addEventListener('scroll', function(e) {
var currentScrollTop = document.getElementById('content').scrollTop;
if(currentScrollTop < lastScrollTop) {
// Upwards scroll!
document.body.scrollTop -= 10;
} else {
// Downwards scroll!
document.body.scrollTop += 10;
}
lastScrollTop = currentScrollTop;
});
I'm sending you a pull request now: https://github.com/patrickmarabeas/marabeas.io/pull/5
how about using document.body.scrollTop -= 1? I don't hava a try, just a guess

jQuery Mobile prevent scroll-to-top before page transition?

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 :)

Categories