Why is $.browser deprecated - and what is a better alternative? - javascript

So I know $.browser has been deprecated and "frowned upon", since jQuery 1.3, but it continues to exist & work in the code.
It's still using the plain javascript: navigator.userAgent to determine the browser being used, as well as the version.
Now is there something about these I don't know about navigator itself, that I shouldn't be using either $.browser or plain vanilla JS to get the browser/version? I just want to make sure when they have IE8 (for example), they really do have it, and I'm not processing the wrong code.
What other alternatives do we have for browser sniffing? I know about $.support, I use modernizr, but sometimes I need just need the down and dirty browser version, instead of seeing what the browser is capable of handling (I think that is a completely different problem solver).

You kind of answer the question yourself. The ideal is to check for feature support. As more browsers and devices come onto the market this approach should scale.
However if you want to do something 'down and dirty' then browser detection of course works, but only so far as you will know your code works in the existing set of browsers (or even just those you've tested your code with).

Generally it's recommended not to try to guess what the browser is but to check if a function is available. There are too many browsers and variants.
To check if a function is available, you simply do this :
if (!Array.prototype.map) {
// not available, shut down computer !

If a "must" to know which browser on the page for me, I use this personally;
(function() {
var re_browsers = {
firefox: /firefox\/([\d\.]+)/,
chrome: /chrome\/([\d\.]+)/,
safari: /webkit.*?version\/([\d\.]+)/,
opera: /opera.*?version\/([\d\.]+)/,
ie: /msie\s+([\d\.]+)/
// ...
};
var ua = window.navigator.userAgent.toLowerCase(), k, re, browser = {};
for (k in re_browsers) {
if (re = re_browsers[k].exec(ua)) {
break;
}
}
browser[k] = true;
browser["version"] = parseFloat(re && re[1]);
browser["versionOrig"] = re[1];
jQuery.extend({browser: browser});
})();

Related

Discover Quirks Mode in IE

I am working on modernizing an older SAAS software. I am their first front end person. They currently only support older IE browsers - and tell their users to turn on quirks mode in newer IE browsers to their software still works.
During the slow process of modernizing I still need those users software to work and not fall apart.
Is there a conditional comment, javascript or other functionality that could let me on the front end know that the browser has been set to quirks mode manually?
I don't want to turn it off, as it is making other parts of the system work, I just need to be able to add a quirks mode to the html tag so that I can work out the kinks in css.
Thanks in advance.
Edit
OK, I have a js solution, well almost... This will give me an alert every time, but will only add the class to the html when I manually change the mode in ie. Any ideas?
$(document).ready(function() {
var quirksMode = (document.compatMode == 'BackCompat');
var isIE = ($('html').hasClass('ie'));
if ( quirksMode && isIE ) {
$('html').addClass('quirks');
alert('IE Quirks');
}
});
OK, I also need to find if they are in Document Mode IE 7 Standard manually, I know this is a mess, but they need it and I think it's important enough to make this happen. I am having the same issue with it not putting the class on unless I am changing the stuff manually, not just on load. Here is this code... it's in the same document ready from above.
if ( document.documentMode == 7) {
$('html').addClass('ie7_standard');
alert('IE 7 Mode');
};
var quirksMode = (document.compatMode == 'BackCompat');
var isIE = ($('html').hasClass('ie'));
if ( quirksMode && isIE ) {
$('html').addClass('quirks');
};
if ( document.documentMode == 7) {
$('html').addClass('ie7_standard');
};
This solves this issue. It adds a class to html if you have Quirks mode in IE or IE7 Standards Document Mode set manually.
F12 in IE won't always show the new class name, but if you have css tied to that class, it will function.
Thanks for your help everyone!
I used this question (How to detect Render Mode of browser for current page?) as a starting point, but it seemed to be slightly outdated.

JQuery not loading in IE9 down

My site is http://www.thetruenorth.co.uk/
I can't get JQuery to work on my site in IE9 down. It works fine in every other browser.
I've realised that it is the code below, which detects if it's a small screen (mobile), that stops it from working. If I remove this bit, everything works. I use this because I don't know how else I'd disable JS for mobiles, but keep it for desktop. Suggestions welcome.
$(document).ready(function(){
if(matchMedia('only screen and (max-width: 1023px)').matches)
{}
else {
CODE HERE
}
});
I have a feeling there's a bug or something that I'm not aware of. Please could someone put me out of my misery?
Thanks
Simple Debugging in IE9
Open IE9
Press F12 to open the Developer window
Click the 'Script' tab
Click 'Console' on the right pane
Attempt to load your page
You will see the following error:
SCRIPT5009: 'matchMedia' is undefined
scripts.js, line 2 character 2
IE9 does not support the 'matchMedia' function and thus does not define it. Attempting to reference it in code stops the execution of the JavaScript completely at that point because it doesn't know what to do with a reference to something that is undefined.
What is going on
jQuery is loading on your page. You can confirm this by typing '$' into the text input line below the console output and press enter. The console will output some data about how $ is defined. This is a very good sign that jQuery loaded. It isn't conclusive in all situations, but for this one we are set.
What is happening is that your callback that is running onDomReady (via $(document).ready(...)), but it is erroring on the very first line. This error causes the rest of the callback to not execute.
Verifying Functionality Support
You can use caniuse.com to check to see what browsers support functionality (JS, CSS, etc). In this case: http://caniuse.com/matchmedia. You will note that IE10 is the first version that supports the matchMedia function. You can assume that in any earlier version you will not have matchMedia by default and referencing it will cause errors.
What You Can Do Now
On the caniuse.com site, at the top is a horizontal list titled "Resources". In this area you will generally find ways to patch browsers that do not support specific functionality.
In the case of matchMedia there is a link to a 'polyfill' which will use custom js to emulate the functionality of matchMedia. The url is: https://github.com/paulirish/matchMedia.js/.
Polyfills sometimes have limitations or catches to using them so be careful. It is also interesting to note that the matchMedia polyfill was written by Paul Irish, who is a very public figure for web technologies.
A Note On Conditional IE Includes
IE supports conditional comments, so you can include the polyfill defined above only for specific versions of IE; in your case anything < IE10. This is documented on the MDN here: http://msdn.microsoft.com/library/ms537512.aspx
<!--[if lte IE 10]]>
<script src="polyfill.js"></script>
<![endif]-->
This is done so that we can use the browser's implementation when possible (generally faster and potentially with more functionality) and polyfill only when needed.
j08691 found the problem you have.
If you need matchMedia to work with IE9 and down, or Firefox 6 and down or Safari 5.1 and down you must shim it. Here is a polyfill for matchMedia which will let you use it on older browsers.
Note, this is not a jQuery issue, this issue is with matchMedia browser support
That's because matchMedia only works with IE10.
Ref: https://developer.mozilla.org/en-US/docs/DOM/window.matchMedia
You may be better off doing this with PHP. ie probably isn't able to run matchMedia correctly. I always keep things like that on the server side because that'll run the same for any client. If you're using PHP try get_browser(). Really easy to write a quick if statement. Check the examples if you need help.
Andrew Martinez's answer is fairly thorough and correct, and I personally found it to be very useful.
The markup for getting the matchMedia method in IE9 would look as follows
<![if lt IE 10]>
<script src="scripts/matchMedia.js"></script>
<![endif]>
I just check if the browser is Chrome or not and then add the matchMedia code from github, have a look below:
$(document).ready(function() {
var isChrome = !!window.chrome;
if (isChrome == true) {
//do this for chrome
} else if (isChrome != true) {
//do this for all other browsers including IE
//so copy and paste current matchMedia.js script form here https://github.com/paulirish/matchMedia.js/blob/master/matchMedia.js like below
/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas, David Knight. Dual MIT/BSD license */
window.matchMedia || (window.matchMedia = function() {
"use strict";
// For browsers that support matchMedium api such as IE 9 and webkit
var styleMedia = (window.styleMedia || window.media);
// For those that don't support matchMedium
if (!styleMedia) {
var style = document.createElement('style'),
script = document.getElementsByTagName('script')[0],
info = null;
style.type = 'text/css';
style.id = 'matchmediajs-test';
script.parentNode.insertBefore(style, script);
// 'style.currentStyle' is used by IE <= 8 and 'window.getComputedStyle' for all other browsers
info = ('getComputedStyle' in window) && window.getComputedStyle(style, null) || style.currentStyle;
styleMedia = {
matchMedium: function(media) {
var text = '#media ' + media + '{ #matchmediajs-test { width: 1px; } }';
// 'style.styleSheet' is used by IE <= 8 and 'style.textContent' for all other browsers
if (style.styleSheet) {
style.styleSheet.cssText = text;
} else {
style.textContent = text;
}
// Test if media query is true or false
return info.width === '1px';
}
};
}
return function(media) {
return {
matches: styleMedia.matchMedium(media || 'all'),
media: media || 'all'
};
};
}());
//below you can add your own matchMedia code
}
});

Javascript, detect touch devices

I'm using this function to detect if the device is a touch device:
function is_touch_device()
{
return !!('ontouchstart' in window) || !!('onmsgesturechange' in window);
};
Got this function from here: What's the best way to detect a 'touch screen' device using JavaScript?
But since Chrome 25 (25.0.1364) it returns true on my desktop which isn't a touch device.
Also I've updated IE9 to IE10 and it returns true in IE!
Searched around but couldn't find anything useful to fix this except using a something like this: http://detectmobilebrowsers.com/
What do you recommend?
I'm looking forward to your responses!
The code works just fine, the browser is able to understand touch events, just because your screen isn't touchable doesn't mean that the browser doesn't support the functionality. What you are looking to test is a hardware capability which isn't really testable. You can always use different ways though of seeing if the user is actual using a touch interface after touching it once, such as this article describes, or many others that larger libraries use such as Modernizer.
As a reference the code actually used in the article above is:
function isTouchDevice() {
var el = document.createElement('div');
el.setAttribute('ongesturestart', 'return;');
if(typeof el.ongesturestart == "function"){
return true;
}else {
return false
}
}
This seems to work:
function isTouchEnabled() { return !!document.createTouch; }
You could use Modernizr to detect touch capability.
This question is very similar to What's the best way to detect a 'touch screen' device using JavaScript? and should perhaps be considered a duplicate.
i was experiencing a false positive IE10 touch issue as well when I was visiting the site i've been working on from my laptop. The original is_touch_device method, i used basically the same thing. I modified the latter half of that statement to be the following:
function is_touch_device()
{
return !!('ontouchstart' in window) || (!!('onmsgesturechange' in window) && !!window.navigator.maxTouchPoints);
}
window.navigator.maxTouchPoints seems to be something specific in IE10 based on this post: http://msdn.microsoft.com/en-us/library/hh772144(v=vs.85).aspx
You can use 51dergees.mobi for detection on the server appropriately changing page view. It has HasTouchScreen, IsSmartPhone, IsTablet properties etc.

Why is javascript saying that addcallback function is not defined?

my first time on here.
My problem is with AS3, Javascript and possibly the browsers Firefox and IE.
I have done so much searching for an answer so i will print my code:
i am using this line to call the flash application and in all browsers its combatible and actually traces in firebug to hold an OBJECT->FLASH_ID so thats not the problem.
var obj = document.getElementById('test');
then i use addcallback:
obj.sendStatus(loggedIn);
now whats weird is that i trace all individual elments in chrome and
-obj = flash object
-sendStatus = flash->function
-loggedIn = either false or true;
everything works great but when i am on firefox or ie
it traces differently
-obj = flash object
-sendStatus = undefined
-loggedIn = either true or false;
now what am i missing??????????
i tried embedding rather than object insertion
i made sure that the id's were all unique
i checked to make sure i had the right flash object selected with getElementById
im so confused.. and it feels like something simple.
I know about some browser - dependent timing problems, making the interface of the flash object available...
A timer could help, try this:
var obj = document.getElementById('test');
setTimeout(function(){obj.sendStatus(loggedIn);}, 500);
500 is a bit to long, but just to be sure. If it works you can try to lower it to 200 - 300.
make sure you declared allowScriptAccess = sameDomain both in embed tag and object tag
in case you don't use swfObject
Maybe the way you get a reference to the swf is wrong, try this
function thisMovie(movieName) {
if (navigator.appName.indexOf("Microsoft") != -1) {
return window[movieName];
} else {
return document[movieName];
}
}
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/external/ExternalInterface.html
The problem is that using ExternalInterface requires both parties (browser and flash) to be ready.
You can have the flash poll a method in the page which just returns true so that you know its ready to receive calls from flash.
On the flip side if the page is cached, it can sometimes happen that the page wants to send to flash before flash is ready, so I use a callback to the page telling it flash is ready, so its like a handshake, once both parties are ready, then we can start sending data back and forth.
This has been my approach since Firefox 3.

Check browser compatibility for HTML5 History API support?

Is there any way to check a browser whether it supports 'HTML5 History API' using JavaScript.
Do I have to check all the browsers and its versions with a long list of condition in if statement.
Or simply like checking any object of function using 'if' statement is enough???...
Checking for the existence of a pushState() method on the global history object should be sufficient.
function supports_history_api() {
return !!(window.history && history.pushState);
}
For more general HTML 5 feature detection I'd look at Modernizer
http://diveintohtml5.info/detect.html#modernizr
This will insulate your code from the messy specifics of each test, making the code more readable and less error prone. With the Modernizer script on your page you'd just do:
if (Modernizr.history) {
// history management works!
} else {
// no history support :(
// fall back to a scripted solution like History.js
}
Checking for history.pushState and history.replaceState objects existence should be sufficient, as it's generally sufficient with feature detection in general.
You can use canisuse.js script to detect if your browsers supports history or not
caniuse.history()
You can check weather or not a function is registered:
if (typeof history.pushState != 'undefined') {
//Enabled
}
Then just replace //Enabled with whatever you wish to do if it's supported.

Categories