I'm try to add some css that will need to execute on iPad 3, but not iPad 4 or vice verse. I'm able to target both leaving the old version with:
#media
only screen and (-webkit-min-device-pixel-ratio: 2),
only screen and ( min--moz-device-pixel-ratio: 2),
only screen and ( -o-min-device-pixel-ratio: 2/1),
only screen and ( min-device-pixel-ratio: 2),
only screen and ( min-resolution: 192dpi),
only screen and ( min-resolution: 2dppx) { }
but so far I can't find a difference to target between 3 and 4. Any css or JS solutions out there. Any help will be greatly appreciated
You can't get any difference by using media queries or user-agents:
Media queries are the same
User Agent contains only iPad word, not version. Other info in UA is about iOS or Safari browser. iPad3 has iOS6 be default, but in can be updated for new versions. Safari depends from iOS version, so system and browser information is imprecise.
So there is only javascript+iOS feature detecting like was with iPad and iPad2 difference in event.acceleration, but there is no different in features of iPad3 and iPad4.
So you can't detect iPad3 only. May be you post here the problem with iPad3 and we can help you to solve it?
BUT:
If you use WebView component, you can do it in it. You can detect in by systemInfo.machine string in Objective-C:
NSString *machineName = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
machineName for iPad3 are iPad3,1, iPad3,2 and iPad3,3. iPad4 are iPad3,4, iPad3,5 and iPad3,6 (don't ask why:)
And in WebView you can change your css file to iPad3.css by using WebResourceLoadDelegate for example.
Confirming that you can't get any difference by media queries or user-agents, I've found a difference between iPad3 and iPad4 using WebGL and js.
Using EXT_texture_filter_anisotropic and its extension object MAX_TEXTURE_MAX_ANISOTROPY_EXT you can return the maximum available anisotropy for a texture.
IPad3 returns 2, iPad4 returns 16
I guess this is due to their different GPU.
Demo
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Anisotropy</title>
</head>
<body>
<p style="font-size: 100px;" id="anisotropy_val"></p>
<canvas id="webGLCanvas" width="400" height="400">
</canvas>
</body>
<script>
function check_max_anisotropy() {
var canvas = document.getElementById("webGLCanvas");
var gl = canvas.getContext("experimental-webgl");
var ext = (
gl.getExtension('EXT_texture_filter_anisotropic') ||
gl.getExtension('MOZ_EXT_texture_filter_anisotropic') ||
gl.getExtension('WEBKIT_EXT_texture_filter_anisotropic')
);
if (ext){
var max = gl.getParameter(ext.MAX_TEXTURE_MAX_ANISOTROPY_EXT);
}
document.getElementById("anisotropy_val").innerHTML = max;
}
check_max_anisotropy();
</script>
</html>
Related
I've been trying to create a popup launcher that fits the screen without overlapping Windows' taskbar, I've done some research, and even created the HTML file, but it doesn't quite work properly, it overlaps the taskbar and even goes beyond it. How can achieve such task, and what am I doing wrong?
Code: ( Run it on your desktop )
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>winds</title>
</head>
<body>
<script>
function fc()
{
window.open('http://www.google.com.br','window','menubar=yes,screenX=0,screenY=0,top=0,left=0,location=no,status=no,toolbar=no,scrollbars=yes,resizable=no,width=' + (screen.width - 10) + ',height=' + screen.availHeight);
}
</script>
Chrome
</body>
</html>
It turns out window.outerWidth and window.outerHeight have been around a while but did not show up in IE until IE9.
The following code example opens a window with maximum size but clear of task bars by first opening it with minimum size and then resizing the opened window to occupy all of the available area.
function splashOpen(url)
{
var winFeatures = 'screenX=0,screenY=0,top=0,left=0,scrollbars,width=100,height=100';
var winName = 'window';
var win = window.open(url,winName, winFeatures);
var extraWidth = win.screen.availWidth - win.outerWidth;
var extraHeight = win.screen.availHeight - win.outerHeight;
win.resizeBy(extraWidth, extraHeight);
return win;
}
// and test
splashOpen("javascript:'hello folks and world'");
Noting:
the MDN wiki example of a window features string appears to be incorrect: include the names of features required and omit those not required.
Users may have selectively disabled suppression of widow.open features. (In Mozilla Firefox see about:config under dom.disable_window_open_feature to prevent popups hiding location details or disabling other useful features.)
Okay, so, the problem I am facing is this: my mobile Firefox browser is not retrieving the correct values for window.innerWidth, document.documentElement.clientWidth, or even the width of a div styled to take up the whole client window after page load.
I am not crazy, my code works just fine in every other browser! For some reason Firefox initializes these values with defaults and then gets the correct values later on. If at any point I interrupt my JavaScript with an alert(), these properties magically become accurate afterwards.
I have scoured the internet for an answer and all I can find is a hack workaround: use window.setTimeout to delay the use of these properties until they have time to populate correctly. That is crazy! Users want speed, not an extra delay just to view my site on a Firefox browser.
What I don't understand is that I can set a div up to fill the client window perfectly before the values become accurate. I do this in css by setting width and height of my div's id to 100%. document.documentElement is basically the same as document.getElementById("my_div"); after all the document elements have loaded, so, how does the browser know how big the div should be when it doesn't have the correct dimensions of the client window in the first place?
I have tried running my code inside a window.addEventListener("load",function(event_){ //My Code }); but still these values will not generate. Is there a page load event that comes after window.onload?
If anyone can tell me why only Firefox mobile seems to display this odd behavior I will give you a mental high five.
Here's a bit of sample code for recreating the problem:
<!DOCTYPE HTML>
<html>
<head>
<!-- Added " after javascript during edit. -->
<script type="text/javascript">
window.addEventListener("load",function(event_){
var output=document.getElementById("output");
/* Returns some default value like 980. */
output.innerHTML=window.innerWidth;
alert("After this alert, the value will change.");
/* Returns an accurate value like 511. */
output.innerHTML=window.innerWidth;
});
</script>
<!-- Added title during edit. -->
<title>Title</title>
</head>
<body>
<p id="output">Default Output</p>
</body>
</html>
My Firefox for android version is 35.0.1. My Android version is 4.4.4. On my device, Firefox displays "980" in the output p element, shows the alert, and then displays "980" again. After page refresh, the first two steps remain the same, but the output after the alert changes to 360. This happens with document.documentElement.clientWidth as well. No properties I try seem to get the correct values. It seems that Firefox has some sort of delay after page load before it has access to the client window's dimensions...
I tried the verge.airve.com plugin without JQuery and its initial feedback remained at 980. It also initialized as 980 on Chrome, which was weird, because Chrome worked as expected without it...
After much debate a solution was found! Firefox apparently resizes the window after it is loaded (I guess for good measure, who really knows)! So, by adding a resize event handler in addition to window.onload, this problem can be averted! See accepted answer below for more details.
Make sure your measurement is done when whole document is loaded and resized.
window.onload = showViewport;
window.onresize = showViewport;
function showViewport() {
var output=document.getElementById("output");
var width = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
var height= Math.max(document.documentElement.clientHeight, window.innerHeight || 0)
output.innerHTML = "Viewport size is " + width + "x" + height;
}
<body>
<p id="output">Default Output</p>
</body>
The problem (innerWidth === 980) persists for Firefox 40.0 under Android 4.4.4. A 1 msec wait is a circumvention. Replace window.onload = myProgram; by
window.onload = function() {setTimeout(myProgram, 1)};
In the meantime I encountered this problem while adapting a fairly elaborate site to small screens. Firefox obeys the CSS following "#media only screen and (max-width: 768px)". However, when one tries to set event handlers depending on device widths, Firefox fails miserably. I needed the above trick with 0.5 second wait at all spots where I picked up the device width. This wait time was necessary for Nexus 7 (2012), but who knows what is needed for other devices?
I can confirm the issue, for example in Firefox 38.0.1 on Android 4.1.2. Created a js bin for testing purposes.
I'd like to check window.innerWidth for custom DOM manipulations on different resolutions (mobile, tablet and desktop size), so it'd be important to get the correct window.innerWidth value already in the document.ready() state and not just only in the window.load().
$('#inline').html($(window).width());
$(document).ready(function() {
$('#ready').html(window.innerWidth);
});
$(window).load(function() {
$('#load').html(window.innerWidth);
});
setTimeout(function() {
$('#setTimeout').html(window.innerWidth);
}, 1000);
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>JS Bin</title>
</head>
<body>
<p><span id="inline"></span></p>
<p>$(document).ready(): <span id="ready"></span></p>
<p>$(window).load(): <span id="load"></span></p>
<p>setTimeout(1000): <span id="setTimeout"></span></p>
</body>
</html>
(I wanted to add only a comment, and not answer, but no reputations yet to do so :-)
I was facing the same issue while using BrowserComponent in CodeNameOne and Android
My solution was to put the js inside a function like so
function runScripts()
{
//get width here
}
And listen to the onLoad event of the BrowserComponent to execute this script once the browser has been fully loaded
like so:
BrowserComponent browser = new BrowserComponent();
browser.addWebEventListener("onLoad", new ActionListener() {
public void actionPerformed(ActionEvent evt) {
browser.execute("runScripts()");
}
});
browser.setURL("http://www.URL.com");
Handling window.onload in the html wasn't enough to wait for the appropriate width to be served
Besides this solution I also found that window.setTimeout(runScripts, 500); works to get the right document width, at the expense of wasting half a second
window.setTimeout(yourFunction, 1);
This did the job for me, 1ms is enough.
A very hack solution I found is to invoke a fake link in the header. My guess is the time delay allows updating of window.innerWidth and window.innerHeight prior to script execution.
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/fake.css"/>
I had the same problem, getting varying width when fetching window.innerWidth on an android device with Firefox. I tried some of the suggestions above, but without success - possibly implementing the examples in a wrong way?
However, by using the code below, I got a system that seems to be working 100% as far as I have tested. It also makes little delay as it break the loop as soon as it get a stable result.
var canvasWidth = 0;
var canvasHeight = 0;
var previousWidth = -1;
var previousHeight = -1;
while ((canvasWidth != previousWidth) || (canvasHeight != previousHeight))
{
previousWidth = canvasWidth;
previousHeight = canvasHeight;
canvasWidth = window.innerWidth;
canvasHeight = window.innerHeight;
}
Long version
I've built a responsive webdesign for just two devices. Simplied example:
<link rel="stylesheet" media="screen and (min-width: 769px) and (max-width: 1199px)" href="tablet.css" />
<link rel="stylesheet" media="screen and (min-width: 1200px)" href="wide.css" />
This works as intended, on all major browsers, tablets (built with Bootstrap 3). The only issue that I have is that there are still people in this world that zoom their browser to 150+% in order to increase readability. This is not an issue, the page still works properly.
There is just one issue - the browser loads the "tablet" view on a 150+% zoomed in webbrowser. AFAIK this is normal behaviour, since there are less pixels available in the viewport, the appropriate media query loads the tablet.css file, just like when you resize the browser screen manually.
I'd like to counter this behaviour by forcing the desktop view, even when zoomed in. Can anyone point me in the right direction?
TLDR:
I've got a RWD scaling for tablet and desktop. Desktop browser zoom 150% = tablet view. How to prevent tablet view for desktop when zoomed in?
Note:
I'm using the viewport meta tag
No, this is not the issue explained here (http://blog.55minutes.com/2012/04/media-queries-and-browser-zoom/)
I've tried using media="screen and (min-device-width: 1200px) but that option renders me unable to 'test' the tablet-view on desktop since 'resizing' a screen simply doesn't work (device width = 1920px)
This will probably work. It's not something I would consider doing because if a user is always zoomed, they are used to things not looking the same and I don't think it's a big deal if your site is fluid and responsive. You will probably get FOUC.
First make an id for your style sheets:
<link id="responsivecss" href="responsive.css" rel="stylesheet" type="text/css" />
<link id="desktopcss" href="desktop.css" rel="stylesheet" type="text/css" />
Use a script to detect touch and no-touch. It's worked for me on Android, IOS, and Windows.
/* __________________ SUPPORTS TOUCH OR NOT __________________*/
/*! Detects touch support and adds appropriate classes to html and returns a JS object | Copyright (c) 2013 Izilla Partners Pty Ltd | http://www.izilla.com.au / Licensed under the MIT license | https://coderwall.com/p/egbgdw */
var supports = (function() {
var d = document.documentElement,
c = "ontouchstart" in window || navigator.msMaxTouchPoints;
if (c) {
d.className += " touch";
return {
touch: true
};
} else {
d.className += " no-touch";
return {
touch: false
};
}
})();
Then load or not load, this is an example, you can remove the second if, if not necessary:
$(document).ready(function () {
if ($('html').hasClass('touch')) {
$('#desktopcss').prop('disabled',true);
}
if ($('html').hasClass('no-touch')) {
$('#responsivecss').prop('disabled',true);
}
});
Quick demo, I haven't tested actual touch devices, but you can do a quick test by hard coding the class on the html element:
http://jsbin.com/gamir/1/edit
I'm developing an application for Ipad. So I need to change the image rendering depending upon the devide wheteher it is ipad or ipad-retina . So can anybody tell me how to detect the difference between ipad and ipad-retina? Thanx!!!!!!!
var isRetina = window.devicePixelRatio > 1;
Check this out: Detect retina displays with javascript.
var retina = (window.retina || window.devicePixelRatio > 1);
Resource: http://hjzhao.blogspot.in/2012/07/detect-retina-display-using-javascript.html
Also use Modernizr
https://github.com/benlister/utilities/tree/master/Modernizr%20Retina%20:%20HiDPI%20test
I'm having a problem detecting a retina iPad (and similar devices) using just screen.availWidth and window.devicePixelRatio. The problem is that iPhones and iPads give the number of dips for screen.availWidth whereas android devices seem to report the number of physical pixels so I can't reliably do screen.availWidth / window.devicePixelRatio to calculate if the screen is of a tablet size.
Is there some other DOM property I can use to help me?
edit - To sum up in a way which hopefully makes clear that the question isn't a duplicate
How can I tell if screen.availWidth reports a value that has already been adjusted to take account of window.devicePixelRatio
That should help
var retina = (window.retina || window.devicePixelRatio > 1);
UPDATE
Retina.isRetina = function(){
var mediaQuery = "(-webkit-min-device-pixel-ratio: 1.5),\
(min--moz-device-pixel-ratio: 1.5),\
(-o-min-device-pixel-ratio: 3/2),\
(min-resolution: 1.5dppx)";
if (root.devicePixelRatio > 1)
return true;
if (root.matchMedia && root.matchMedia(mediaQuery).matches)
return true;
return false;
};
I haven't tested this, but here's an approach I think might work. I'll do a jsbin for it when I get time.
Because all devices (to the best of my knowledge) adjust for devicePixelRatio before passing the value to CSS media queries we can (in slightly pseudo code)
measure window.devicePixelRatio and screen.availWidth
Write a style tag to the head which includes a media query something like the following
#my-test-el {
display: none;
visibility: visible;
}
#media screen and (min-device-width:screen.availWidth) {
#my-test-el {
visibility: hidden;
}
}
Append <div id="my-test-el"> to the page
Read off the style.visibility attribute. If it equals hidden then the css value is the same value as screen.availWidth => screen.availWidth has been preadjusted for dpr.
edit It works! http://jsbin.com/IzEYuCI/3/edit. I'll put together a modernizr plugin too
edit And here's the pull request to get it in Modernizr - https://github.com/Modernizr/Modernizr/pull/1139. please upvote if you'd find it useful
This Modernizr plugin may help : Modernizr Retina : HiDPI Test
Note: Requires Modernizr's Media Queries feature