On Android you can work out the current zoom by adding an absolute div to the body of width 100%, and dividing the div's offsetWidth by window.innerWidth
.
var iPadMeasureWidthNode = window.iPadWNode;
if (!iPadMeasureWidthNode) {
iPadMeasureWidthNode = window.iPadWNode = document.createElement('div');
// .ipad-measure-w {position:absolute; width:100%; top:-1px}
iPadMeasureWidthNode.className = 'ipad-measure-w';
document.body.insertBefore(iPadMeasureWidthNode, document.body.firstChild);
}
var zoominverse = 1000 / Math.round(1000 * iPadMeasureWidthNode.offsetWidth / window.innerWidth);
You can keep an element at 1:1 zoom by inverting (undoing) the amount of zoom:
// Not using scale3d because is hardware zooming which is ugly unreadable blurry pixel magnification.
node.style.webkitTransform = (zoominverse > 1) ? 'scale(' + zoominverse + ')' : '';
node.style.webkitTransformOrigin = (zoominverse > 1) ? '0 0 0' : '';
Zoom change is detected by window.onresize
event (although resize event is delayed until after resize is completed... you can detect zoom start using the gesturestart
event on iPad, or document.touchstart
event and detect 2 fingers down).
Edit: After three corrections saying it doesn't work, I thought I better add an example showing it working. Tested works on: Android 4.1.2 normal browser, Android 4.1.2 Chrome, Android Opera Mobile 12.10, iPad 2 iOS4. (Didn't work on Android Firefox Mobile, and won't work in an iframe so jsfiddle won't work).
<!DOCTYPE html>
<html>
<head>
<style>
.ipad-measure-w {
position: absolute;
width: 100%;
top: -1px;
};
</style>
</head>
<body>
<button onclick="alertWidth()">alertWidth</button>
<div style="width: 1600px; height: 100px; background-color: blue;"></div>
<script>
function alertWidth() {
var iPadMeasureWidthNode = window.iPadWNode;
if (!iPadMeasureWidthNode) {
iPadMeasureWidthNode = window.iPadWNode = document.createElement('div');
iPadMeasureWidthNode.className = 'ipad-measure-w';
document.body.insertBefore(iPadMeasureWidthNode, document.body.firstChild);
}
var zoominverse = 1000 / Math.round(1000 * iPadMeasureWidthNode.offsetWidth / window.innerWidth);
alert(zoominverse);
}
</script>
</body>
</html>