Disable jQuery Mobile transition when going back in iOS7 Safari history - jquery-mobile

As described here in Safari on iOS7 - if you swipe in from the left of the screen it triggers a history back event as if the user clicked the back button.
The default behavior of jQuery Mobile is to reverse the transition that was used to reach a particular page when going back to the previous page. This works great when using the < and > buttons but looks terrible when swiping in from the left.
Is there a way to completely disable transitions in the 'reverse' direction using jQuery mobile?

Just capture the pagecontainerbeforetransition event on the page widget.
You can then look at ui.options.reverse and cancel the transition. If you want you can detect iOS7, but I think I'll just give this to all my visitors.
$(document).on("pagecontainerbeforetransition", function (event, ui)
{
if (ui.options.reverse == true)
{
ui.options.transition = "none";
}
});
Here's a sample of a typical ui.options object.
{"reverse":true,"changeHash":false,"fromHashChange":true,"showLoadMsg":true,
"allowSamePageTransition":false,"transition":"none"}
For some reason reverse always seems to be true even when navigating forward. May be a but, but I decided to check for it anyway.

Related

after jQuery mobile pageShow silentscroll, page jumps to top

We have a basket page, where there are the products, and then the shipping methods. This is a jQuery mobile site.
What I want to achive, that if a shipping method selected, then if there is a page reload, jQuery mobile jumps to a div to the shipping methods.
Here is the code, what scrolls to the shipping methods. This is an inline script.
$(document).on("pageshow", function (e, ui) {
$.mobile.silentScroll($('#kosar').offset().top);
});
Expected result: on page refresh, the window scroll to the #kosar div.
Current result: page scrolls to the #kosar div, but immediatly scroll to the top of the page.
What we discovered, if some error is occures after the silentScroll, the window is not jump back to the top of the page. So it seems, something after the pageshow scrolls it to back, but we do not know, what.
For example:
$(document).on("pageshow", function (e, ui) {
$.mobile.silentScroll($('#kosar').offset().top);
undefined_function(); //This function is not exists
});
Here are the non working, and "working" examples:
Here is a live example. When you refresh the page, you will see for a second the big red text, and immediatly after that you will be taken to the top of the page.
Here is the example with error.
I've tested it in FF Developer Edition. With Chrome, you need to resize your browser to a littlebit smaller, and refresh some times to see the scrollbar how jumping to bottom and up.
How can I prevent this annoying scroll to top?
I think, this is a bug in the jQuery mobile js, I've reported it to them.
Finally I figured it out.
Version:
http://ajax.googleapis.com/ajax/libs/jquerymobile/1.4.5/jquery.mobile.min.js
I've made a breakpoint in the jQuery mobile js silentScroll definition, and what I've see, for some reason it run twice. The first is a good call, ypos is a number, where I want to jump, this is why it jump to the right place.
But, later, at line 15432 here are these lines of codes, what is running on document ready:
// window load event
// hide iOS browser chrome on load if hideUrlBar is true this is as fall back incase we were too early before
if ( $.mobile.hideUrlBar ) {
$window.load( $.mobile.silentScroll );
}
And when it's happens, on the second call, the ypos for silentScroll will be an object, not a number, as the function expects, and if it not a number, then jQuery mobile set the ypos to $.mobile.defaultHomeScroll what is actually 1 if you do not modified. This is why it jumps back to home.
Warning: If you think, you just need to set the $.mobile.hideUrlBar to false, you are wrong. I've tried it, but it had side effects, because in line 15416 there are another reference for this variable, and if you turn off, then when you go from a page to another, you wont be redirected to the top of your second page.
So the solution was to comment out this $window.load( $.mobile.silentScroll ); and now everything is working as I expected.

jQuery Mobile - elements active on light touch when scrolling

I'm sure that you have seen this kind of problem. I have a page with a list of elements and i have created a class active when i click on them, but when i scroll the page they trigger it (after a light touch) and became "active". I don't know how to do, this is the code which i use now, but it is no perfect because don't work at 100%
$("ul li").bind("vmousedown",function(){
$(this).addClass("active");
}).bind("vmouseup vmouseout scrollstart scrollstop", function(){
$(".active").removeClass("active");
});
Do you have others solutions for this problem?

jQuery Mobile popup that doesn't move when scrolling the page

I am using jQuery Mobile 1.3.0 RC1. I have a popup that I create programmatically at the bottom of my page and close after a few seconds using setTimeout (toast notification). It works very well, however if I happen to scroll the page while the popup is displayed, the popup gets scrolled too. I would like the popup not to move, i.e. stay in its position relative to the screen, not relative to the page. Is there a way to do that ?
I have tried playing with the data-position-to attribute in the HTML element, with the positionTo option of the "open" method, and tried placing the popup element inside a fixed transparent footer, none of these resulted in the desired behavior.
I had a similar problem last week. Finally solved it using modal dialog instead of popups.
For popups, I could find following.
$("#myPopup").on({
popupbeforeposition: function () {
$('.ui-popup-screen').off();
}
});
Which helped me in prevention of closing the dialog while user touched outside of popup. But scrolling issue was still there. So I changed all popups to modal dialogs. Hope it helps someone.

Mobile Safari Web App Zoom issue

I am building a mobile web app that uses jQuery and hammer.js for touch controls. hammer.js has a feature called "prevent_default" which turns off Safari's scrolling/zooming/prettymucheverything. I have a page with a form using < input > for text fields, and a javascript listener that calls .focus() when you tap the form.
This all works well up until a point. The page is fixed in place and looks real pretty, and when you click on a form field it zooms in and the iOS keyboard appears. The problem is that when the user is done entering text, there is no way to zoom out. The browser is so zoomed in from .focus() that the browser bar is gone and you have to close the browser tab and re-type in the URL instead of refreshing.
I am looking for a way to force the browser to zoom out back to the initial view. I've looked all over the internet for some solution but have yet to find anything.
I have the viewport meta tags in the header to disable zooming from the beginning, but is not useful in solving this issue
A hacky solution is to focus and blur an inputfield after you have changed the viewport attributes.
function refreshViewportZoom(){
var viewport = document.querySelector("meta[name=viewport]");
viewport.setAttribute('content', 'initial-scale=0.5, maximum-scale=0.5, scale=0.5, user-zoom=0.5, zoom=0.5');
document.getElementById('myInputField').focus();
setTimeout(blurLater,2000);
}
function blurLater(){
document.getElementById('myInputField').blur();
}
The blurLater is needed as a function, because Safari seems to look ahead and ignore it otherwise.

jQuery buttonset: intercept clicks so that buttons don't change state

I am using jQuery UI buttonset for an on/off pair of buttons, mainly because of the nice styling you get with it. I want to handle clicks so that when you click one of the two buttons you get a dialog where you can make some more choices, and after that the page reloads with the buttons in their new state (if the state was changed, which may not be the case).
The problem is that the button that you click gets styled as selected before any click handlers are called, it seems. I don't want the selection to change, I want to do that manually.
It seems that the click event is bound to the label that jQuery UI creates, and I'm struggling a bit with unbinding it. I guess I'm also asking if there is some other way to get the style without the function... since buttonset doesn't offer any event handlers I need to catch the click events myself anyway.
The solution I'm thinking of right now is simply copying the html that buttonset generates into my code, keep the css and remove the buttonset call. I thought it might worth it to check on StackOverflow before giving up though. :)
Since jQuery UI doesn't trigger any events that run before for the actual selection is made the workarounds to accomplish this are going to be relatively hacky. The best idea I could come up with is to programmatically remember the previously selected option and then attach a click handler that determines whether you should revert jQuery UI's selection of the new button or not.
$('#parent_container').buttonset();
var selectedButton = $('#parent_container :checked');
$('.ui-button').on('click', function() {
setTimeout(function() {
//Insert your actual check here.
if (true) {
selectedButton.attr('checked', true);
$('#radio').buttonset('refresh');
} else {
selectedButton = $('#parent_container :checked');
}
}, 1);
});​
The setTimeout is necessary to ensure that this runs after jQuery UI's click handler. Since you're showing a dialog you might need to alter this to instantly revert the selection, but remember what the user attempted to select for future use.
I have an example of always refusing the user's selection here - http://jsfiddle.net/tj_vantoll/s6XTu/14/
Obviously this is not an ideal approach but it does work. jQuery UI should really add support for selection events; I'll try to get around to filing a ticket for this. The button plugin is due for some updates in 1.11 - http://wiki.jqueryui.com/w/page/12138038/Roadmap.

Resources