I'm no expert in javascript/jquery and have searched and searched to find an answer to my situation. Some answers have been close but I'm not sure how to translate it to my own situation.
I have a form on my website which conveniently zooms in on mobile devices for the user to input their data. After they hit 'submit' the screen zoom remains the same and the post-submit message is not seen since it's out of the viewport.
Is there a way to reset the screen zoom after form submission?
I've found the metatag 'viewport' and can change that so that the zoom function doesn't trigger at all
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
but I'd still like the zoom function to be there...
You can update viewport on form submit, like:-
element.on('submit', function(event) {
var viewportmeta = document.querySelector('meta[name="viewport"]');
if (viewportmeta) {
viewportmeta.setAttribute('content', 'width=device-width, maximum-scale=1.0, initial-scale=1.0');
}
}
Try this.
Related
I have an issue with zooming. I want to block pinch to zoom in Mobile Safari on HTML elements. I use script to prevent default behavior of browser and it is working fine for normal pinching, but when I start scroll with one finger and later add second and pinch Safari still zooming the page...
Has anyone any idea how can I block this zooming?
I'am creating mobile game using canvas and use HTML for message windows so please don't write that it is a bad idea to block zooming for accessibility reasons.
Code to prevent zooming:
document.addEventListener("touchmove", function(event) {
event = event.originalEvent || event;
if(event.touches.length > 1 || event.scale > 1) {
event.preventDefault();
}
}, false);
UPDATE:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
This meta tag doesn't work because Apple disable it in Mobile Safari since iOS 10 up to accessibility reasons
can you test it?
document.documentElement.addEventListener('touchmove', function (event) {
event.preventDefault();
}, false);
I want to allow the user to zoom when he clicked on an image and I don't want to allow him to zoom if there is no image.
// image function
viewport = document.querySelector("meta[name=viewport]");
viewport.setAttribute('content', 'width=device-width, initial-scale=1.0, maximum-scale=5.0, user-scalable=yes');
// no image function
viewport = document.querySelector("meta[name=viewport]");
viewport.setAttribute('content', 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no');
The problem:
If the user can zoom he can't go back to NORMAL disabled zoom because the no image function disables the zoom BUT the zoomfactor is not going back to the normal viewport.
So after the no image function it is possible to zoom but there is a zoom-factor already :/
Do you have any idea how to zoom back to the normal viewport in the no image function?
Thanks!
Don't change the viewport. There is a better way to achieve the same thing -> http://lab.hakim.se/zoom-js/
I'm sure that if you play with the viewport like that you will have problems in most of the mobile devices.
I've encountered similar problems before and could never really understand the workarounds, and so I ended up relying on plugins like iScroll. This is such simple task that I refuse to include a plugin for it - what I want is to prevent horizontal scroll in iOS. This includes the rubber band effect for any content that might be on the page but that isn't visible.
From what I understand I need to disable the rubber band altogether first and then apply the touch scroll to a container element (which I've given the id "touch"). Not sure if this is the right approach?
$(document).bind('touchmove', function(e) {
if (!e.target == '#touch') {
e.preventDefault();
}
});
Style for #touch
-webkit-overflow-scrolling: touch;
overflow: hidden;
height: 100%;
#media only screen and (max-width: 768px) {
width: 768px;
}
This doesn't prevent the horizontal width from staying at 728px however, the user is still able to scroll and see the hidden content. Ideas?
Well, the above metas are useful as such:
<meta content="yes" name="apple-mobile-web-app-capable" />
<meta content="minimum-scale=1.0, width=device-width, maximum-scale=1, user-scalable=no" name="viewport" />
They prevent that bug in Safari that happens when the user rotates the screen. However, the most proper way to accomplish the desired functionality is:
Use a parent div with overflow hidden and make sure the height of this div is limited according to the viewport and a child div with overflow:auto or the css 3 overflow-y:scroll. So basically if the size of the content inside the child div exceeds the default size of the child, you can vertically/horizontally scroll through it. Because the parent has overflow:hidden, the content outside of the child will not be displayed, so you get a proper scroll effect. ** Also, if you use overflow: hidden and prevent default for all touchEvents, there will be no scrolling or weird browser behavior**
With the help of JavaScript, make sure that every element in the DOM is scaled according to the viewport, so avoid using static sizes for as many elements as possible.
Bind the touchStart, touchMove and touchEnd events. Safari doesn't always fire a touchEnd event unless a touchMove event is listened for as well. Even if it's just a placeholder, put it there to avoid the inconsistent behavior in Safari.
Horizontal sliding is possible in two ways: load new content in the same div after you detect the slide direction or populate that child div with all the elements and you are good to go and actually shifting the margins/position of the child inside it's parent to 'scroll'. Animation can be used for a slicker interface.
Bind your touch event listeners. I don't know what library or event management system you are using, but it doesn't matter. Just call the respective function for the respective task.
Get the slide direction(left/right):
var slideBeginX;
function touchStart(event){event.preventDefault();//always prevent default Safari actions
slideBeginX = event.targetTouches[0].pageX;
};
function touchMove(event) {
event.preventDefault();
// whatever you want to add here
};
function touchEnd(event) {
event.preventDefault();
var slideEndX = event.changedTouches[0].pageX;
// Now add a minimum slide distance so that the links on the page are still clickable
if (Math.abs(slideEndX - slideBeginX) > 200) {
if (slideEndX - slideBeginX > 0) {
// It means the user has scrolled from left to right
} else {
// It means the user has scrolled from right to left.
};
};
};
This work for me on Android, iPhone and iPad.
<!doctype html>
<html>
<head>
<meta content="yes" name="apple-mobile-web-app-capable" />
<meta content="minimum-scale=1.0, width=device-width, maximum-scale=1, user-scalable=no" name="viewport" />
<title>Main</title>
</head>
<body>
...
</body>
</html>
Following link might be useful to you, here vertical is disabled and horizontal enabled, you just need to tweak the code a little for your purpose.
jquery-tools-touch-horizontal-only-disable-vertical-touch
In case you aren't concerned about vertical sliding, you can try the following code also -
document.ontouchmove = function(e){
e.preventDefault();
}
Hope it helps.
If you dont use the meta you will always get a rubber band effect.
<meta name="viewport" content="width=device-width" />
Even if the page fitted exactly the user would still be able to stretch the page wider than it should be able to go, you must use the view port to prevent this, there is no other way...
I have an AJAX app built for mobile Safari browser that needs to display different types of content.
For some content, I need user-scalable=1 and for other ones, I need user-scalable=0.
Is there a way to modify the value of the content attribute without refreshing the page?
<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;" />
I realize this is a little old, but, yes it can be done. Some javascript to get you started:
viewport = document.querySelector("meta[name=viewport]");
viewport.setAttribute('content', 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0');
Just change the parts you need and Mobile Safari will respect the new settings.
Update:
If you don't already have the meta viewport tag in the source, you can append it directly with something like this:
var metaTag=document.createElement('meta');
metaTag.name = "viewport"
metaTag.content = "width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"
document.getElementsByTagName('head')[0].appendChild(metaTag);
Or if you're using jQuery:
$('head').append('<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">');
in your <head>
<meta id="viewport"
name="viewport"
content="width=1024, height=768, initial-scale=0, minimum-scale=0.25" />
somewhere in your javascript
document.getElementById("viewport").setAttribute("content",
"initial-scale=0.5; maximum-scale=1.0; user-scalable=0;");
... but good luck with tweaking it for your device, fiddling for hours... and i'm still not there!
source
This has been answered for the most part, but I will expand...
Step 1
My goal was to enable zoom at certain times, and disable it at others.
// enable pinch zoom
var $viewport = $('head meta[name="viewport"]');
$viewport.attr('content', 'width=device-width, initial-scale=1, maximum-scale=4');
// ...later...
// disable pinch zoom
$viewport.attr('content', 'width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no');
Step 2
The viewport tag would update, but pinch zoom was still active!! I had to find a way to get the page to pick up the changes...
It's a hack solution, but toggling the opacity of body did the trick. I'm sure there are other ways to accomplish this, but here's what worked for me.
// after updating viewport tag, force the page to pick up changes
document.body.style.opacity = .9999;
setTimeout(function(){
document.body.style.opacity = 1;
}, 1);
Step 3
My problem was mostly solved at this point, but not quite. I needed to know the current zoom level of the page so I could resize some elements to fit on the page (think of map markers).
// check zoom level during user interaction, or on animation frame
var currentZoom = $document.width() / window.innerWidth;
I hope this helps somebody. I spent several hours banging my mouse before finding a solution.
I have an AJAX app built for mobile Safari browser that needs to display different types of content.
For some content, I need user-scalable=1 and for other ones, I need user-scalable=0.
Is there a way to modify the value of the content attribute without refreshing the page?
<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;" />
I realize this is a little old, but, yes it can be done. Some javascript to get you started:
viewport = document.querySelector("meta[name=viewport]");
viewport.setAttribute('content', 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0');
Just change the parts you need and Mobile Safari will respect the new settings.
Update:
If you don't already have the meta viewport tag in the source, you can append it directly with something like this:
var metaTag=document.createElement('meta');
metaTag.name = "viewport"
metaTag.content = "width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"
document.getElementsByTagName('head')[0].appendChild(metaTag);
Or if you're using jQuery:
$('head').append('<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">');
in your <head>
<meta id="viewport"
name="viewport"
content="width=1024, height=768, initial-scale=0, minimum-scale=0.25" />
somewhere in your javascript
document.getElementById("viewport").setAttribute("content",
"initial-scale=0.5; maximum-scale=1.0; user-scalable=0;");
... but good luck with tweaking it for your device, fiddling for hours... and i'm still not there!
source
This has been answered for the most part, but I will expand...
Step 1
My goal was to enable zoom at certain times, and disable it at others.
// enable pinch zoom
var $viewport = $('head meta[name="viewport"]');
$viewport.attr('content', 'width=device-width, initial-scale=1, maximum-scale=4');
// ...later...
// disable pinch zoom
$viewport.attr('content', 'width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no');
Step 2
The viewport tag would update, but pinch zoom was still active!! I had to find a way to get the page to pick up the changes...
It's a hack solution, but toggling the opacity of body did the trick. I'm sure there are other ways to accomplish this, but here's what worked for me.
// after updating viewport tag, force the page to pick up changes
document.body.style.opacity = .9999;
setTimeout(function(){
document.body.style.opacity = 1;
}, 1);
Step 3
My problem was mostly solved at this point, but not quite. I needed to know the current zoom level of the page so I could resize some elements to fit on the page (think of map markers).
// check zoom level during user interaction, or on animation frame
var currentZoom = $document.width() / window.innerWidth;
I hope this helps somebody. I spent several hours banging my mouse before finding a solution.