Why would my Javascript break on iOS? - javascript

I have this code on jsFiddle that is implemented and works just fine on desktop browsers and works, to a point, on mobile devices. http://jsfiddle.net/heufT/
What my code is doing
If the screen is larger than 960px wide (or thereabouts) a normal horizontal navigation will be displayed, however if the screen is less than 960px wide the navigation becomes apart of a button, which when clicked reveals the same links in a vertical menu instead. When you scroll the page, the header will shrink to a smaller height and if you go back to the top the header goes back to the same height as before. There is also a .load script that will ensure this all happens even when you resize your browser (mainly for use on desktop).
jQuery(document).ready(function($){
// prepend menu icon
$('nav').prepend('<div id="menu-icon"></div>');
/* toggle nav */
$("#menu-icon").on("click", function(){
$("ul#prim").slideToggle();
$(this).toggleClass("active");
});
});
// Navigation resize event on scroll
$(document).scroll(function(){
if($(window).width()>959){
$("ul#prim").addClass("adjTop");
}
if($(window).width()<958){
$("ul#prim").removeClass("adjTop");
}
if ($(this).scrollTop()>105){
// animate fixed div to small size:
$('header').stop().animate({ height: 90 },50, 'linear');
$('ul#prim.adjTop').stop().animate({ top: '50%', 'margin-top': 18 },50, 'linear');
$('ul#prim').stop().animate({ top: 62 },50, 'linear');
$("img.logo").fadeOut();
$("img.bao_logo").fadeIn(1000);
} else {
// animate fixed div to original size
$('header').stop().animate({ height: 175 },50, 'linear');
$('ul#prim.adjTop').stop().animate({ top: '50%', 'margin-top': 18 },50, 'linear');
$('ul#prim').stop().animate({ top: 105 },50, 'linear');
$("img.logo").fadeIn(1000);
$("img.bao_logo").hide();
}
});
$(window).resize(function() {
if($(window).width()>959){
$("ul#prim").addClass("adjTop");
}
if($(window).width()<958){
$("ul#prim").removeClass("adjTop");
}
// Showreel
$(window).resize(function(){
// Resize video to fix aspect ratio when window resizes
// Only do this if video is currently visible
if ($('#showreel').height()!=0){
$('#showreel').height(($('#showreel').width()/16)*9);
}
});
});
(function($){
// Custom scrollbars for work feature on homepage
$(window).load(function(){
$(".scroll-pane").mCustomScrollbar({
horizontalScroll:true,
mouseWheel: false
});
});
})(jQuery);​
The problem
The one thing I have been noticing though on iPad and iPhone especially is that the JS will work but then when you pinch/zoom Javascript completely breaks and the navigation button doesn't work nor does the shrinking/growing of my header.
I have tried disabling pinch/zoom using the meta viewport tag which obviously stops the user from zooming in to the page but even when you at least try to pinch/zoom and it doesn't do anything, i've noticed the JS still breaks and nothing works.
Has anyone got any pointers? Is there any errors in my code that would casue this? Am I missing anything?

Ok so after testing for a couple of days I ended up revisiting the meta viewport tag and added a maximum-scale attribute combined with the user scalable attribute and it cured the problem. Not sure if this is the right way to go about things as the user is prevented from pinch/zooming and therefore impacts usability but this is a short term solution none the less.
My viewport tag now looks like so:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

Related

Disable body scrolling on element

I created a floating sticky bootstrap panel at the bottom right of the screen. It look like a chat support like intercom. When I'm scrolling on the panel the body will scroll too. And it's really weird when I'm scrolling on mobile because I display the panel in full screen and we can scroll on the body while the panel is in fullscreen.
So I put pieces of code in my JS to enable / disable the body scrollbar :
if (...) {
$('body').css('overflow', 'hidden');
} else {
$('body').css('overflow', 'scroll');
}
...
It works and it's overkill I think but I don't found better. But I have another problem. If I go on my mobile the chrome address bar will be hide when I scroll on the full screen panel and it's really ugly because the panel will be redrawed every time.
Do you know a better way to disable body scrolling when the cursor is on certain element (a magic css property ?) and disable auto hiding address bar of browsers ?
If you go on intercom with your mobile it's exactly what I want.
if you need to totally enable or disable scroll you must use this way:
if (...) {
$('html, body').css({ overflow: 'hidden', height: '100%' }); // to hide
} else {
$('html, body').css({ overflow: 'auto (or) scroll', height: 'auto' }); // to show
}
you must include html as just only body is not enough. Hope it helps.

Smooth scrolling page when using jQuery ui resizable

So what I want to know is how can I scroll the page down smoothly as I resize a div past the bottom of the browser.
So far what I have set up is that when you resize the div and it gets to the last 30px of of the browser, it starts to scroll the page down. That part works, but it's jerky when doing so.
My code:
// $maxHeight is set above this, it just takes all the elements within the div and and get's the total height and set that as maxHeight
$('.notifications-drop-down').resizable({
maxHeight: $maxHeight,
minHeight: 400,
handles: {
's': '.ui-resizable-s'
},
resize: function(event, ui){
if((ui.position.top + ui.size.height) > ($(window).scrollTop() + $(window).height() - 30)){
$(window).scrollTop($(window).scrollTop()+10);
}
}
});
What I tried to fix this:
Adding an animate function to the scrollTop to make it smoother
$('html,body').animate({scrollTop: $(window).scrollTop()+30}, 200);
But that does not work smoothly. I have changed the animation duration and it's still not smooth. Does anyone know what I can do it get this to be smooth?
Something I noticed was that when the page scrolls down it does not recognize that the div is in the bottom 30px so it's not recalculating if it should scroll down more (you need to wiggle your cursor while resizing the div for it to work), I did try and add the same code for scrolling down to the resizable's stop function but that didn't help as well.
Thanks for the time.

iPhone anchor, scrollTop, scrollTo reveals mobile button bar, but does not scroll or jump up to anchor

I'm adding a back to top button fixed to bottom of the browser window. When clicked, it scrolls to top in desktop and Android, but not iPhone. On the iPhone, the scrollTo event reveals the address bar and the bottom mobile button bar, but does not return the user to the top of the page.
EDIT: The address bar and button bar on the iPhone appears when a touch event occurs within 20-30px of the bottom of the screen. This is why this back to top button doesn't work. Moving it 40px up stops the address/button bars from appearing.
I've attempted to just place it raw:
$('#scroll-to-top-button').on('click', function() {
window.scrollTo(0,0);
});
And with a timer:
$('#scroll-to-top-button').on('click', function() {
window.setTimeout(function() {
window.scrollTo(0,0);
}, 500);
});
I tried using scrollTop, which had the same results: browser button bar and address bar appear, but no scroll.
I also tried initiating the scrollTo and at the same time setting a timeOut with another scrollTo. The timeout never fires.
I did also try scrolling html or body, or a combination of the two:
$('#scroll-to-top-button').on('click', function() {
$('html,body').animate({
scrollTop: 0,
}, 200);
});
Only html
$('#scroll-to-top-button').on('click', function() {
$('body').animate({
scrollTop: 0,
}, 200);
});
only body
$('#scroll-to-top-button').on('click', function() {
$('html').animate({
scrollTop: 0,
}, 200);
});
I've tried resetting the button to an anchor tag and trying to get it to link within the page. This doesn't work with just basic html anchor functionality:
<div id="main-body"> ... lots of content forcing scrollbars to appear ... </div>
<a id="scroll-to-top-button" class="btn btn-default" href="#main-body">Back to Top</a>
And tried preventing default and animating the link to the anchor:
$('#scroll-to-top-button').on('click', function(e) {
e.preventDefault();
$('html,body').animate({
scrollTop: 0,
}, 200);
});
Here's a link demonstrating the problem. In this link, the code is using one of my last examples down this question, where it's purely an anchor tag trying to link to top of page.
http://willanni.com/dev/iphone-scroll/
I thought maybe missing the viewport tag might be causing it, so I added the following: <meta name="viewport" content="width=device-width, initial-scale=1">. However. When I add that in, it still does not make it work.
Besides forcing the address bar and button bar to always be visible in iPhone, is there a way to get this to scroll to top of window in iPhone? (Note: iPad doesn't have this issue, though it had a different weird issue that required the timeout to fix. Different story though)
Try using jQuery animate on body and html:
$("BODY,HTML").animate({
scrollTop: 0
}, 100);
// second parameter is time so adjust it if you please
The answer is that there really is no way to do this without forcing the address/buttons bar to be always visible.
The iPhone captures any touch event within about 20-30px of the bottom of the screen, and displays the address and bottom buttons bar. No page script, button, or links are triggered or registered as touched until the bar is revealed. A position: fixed, bottom: 0; button then is not able to be activated until the second touch:
First touch reveals the bottom button bar (and address bar)
Second touch activates whatever button/script/anchor functionality is in place
Adding an event listener to the window doesn't capture a touch event in that area of the screen while the button bar is hidden. For example, in order to test I set a timeout to allow myself a bit of time to scroll down and hide the bottom bar. In all areas of the screen except the bottom, this worked:
window.addEventListener('touchstart', function() {
setTimeout(function() {
alert('touchstart');
}, 500);
});
In that bottom region, nothing.
So, in effect, to have a button attached to the bottom of the screen work on first click, you'll need to apply some hacky css to the body and html tags to force the address and button bars to always appear:
html,body {
-webkit-overflow-scrolling: touch !important;
overflow: auto !important;
height: 100% !important;
}

jQuery popup resize on phone

I have a small problem with a popup image displaying on a mobile browser. The popup is displayed on a mouse click and then a resize function sets the size according to the viewport size.
This works fine and is centred in the viewport when opened, but when I tilt the phone to landscape I call a resize function but it doesn't seem to work properly as the newly resized image is off centre in the viewport, this is then repeated when the phone is returned to portrait mode. I have tested the code on android chrome browser.
The resize function I have used is as follows:
$(window).resize(function () {
$(".dialogContent").css({
position: 'absolute',
left: ($(window).width() - $(".dialogContent").outerWidth()) / 2,
top: ($(window).height() - $(".dialogContent").outerHeight()) / 2
});
});
Sorry about posting as an answer but I still can't comment yet.
Based on what you have said I am a little confused about the mouse click portion of your code.
Surly the resize function is not being called when the user clicks the button for the first time. so are you sure that it is working he way you want at all?
To answer your question with a limited amount of understanding of what your code looks like
it should be something like:
$(".dialogContent").css({
position: 'absolute',
left: '50%',
'margin-left': $(".dialogContent").outerWidth() / 2,
'margin-top': $(".dialogContent").outerHeight() / 2,
top: '50%'
});
From my understanding to centre align positioned absolute you set it's top and left to 50% and then offset the positioned absolute element by half.
Now that I'm home I can make you a fiddle here

Responsive setting creates page scrolling issues

I'm having issues with my CarouFredSel carousel.
I have a (tall) one pager with a carousel inside. If I scroll below it, any browser resize will make the page scroll back up about one page (I'm estimating the height of the carousel). I understand a few pixels of twerking, but now that's about 1000...
The problem is, I'd be 'fine' with it if it was only on resize, but this problem reproduces on reaching the bottom of the page on mobile, without any kind of resizing, no screen rotation (on Android, at least, cannot test iOS right now..). And like I explained, I reproduced the problem with slightly resizing a desktop browser on reaching the bottom of the page.
On disabling CarouFredSel, the problem goes away. It also goes away on disabling the responsive option on it.
carouFredSel is initiated like so :
$("#modeles").carouFredSel({
responsive: true,
scroll: {
fx: "crossfade",
duration: 500
},
direction: "left",
items: {
visible: 1,
width: 868
},
auto: false
}, {
transition: true
});
I have created a JS fiddle reproducing the issue here.
Okay so I get alot of these few 'tricky' stuff and what I oftenly do, I back it up with javascript.
In your case, what causes all the problem is Google Maps and the content of the iframe to be more specific.
What I would do in your case - of which does works perfectly - I would set an attribute of the scroll position on scroll, and on resize get me to that scroll position.
That said, we have this:
$(window).scroll(function () {
$("body").attr("xheight",$(document).scrollTop());
});
$(window).on("resize", function(e){
e.preventDefault();
$(document).scrollTop($("body").attr("xheight"))
});
And that's all you need.
Given example:
jsFiddle

Categories