Hello I want to detect the Browser , IE 8 or more will be appropriate for me. For this i used following code but it fails for IE 11 . For other its detecting properly.
function getInternetExplorerVersion()
{
var rv = -1; // Return value assumes failure.
if (navigator.appName == 'Microsoft Internet Explorer') {
var ua = navigator.userAgent;
var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
if (re.exec(ua) != null)
rv = parseFloat(RegExp.$1);
}
return rv;
}
Below is the link which also I tried but couldn't succeed.
You can explicitly detect IE11 with the following check (using feature detection):
if (Object.hasOwnProperty.call(window, "ActiveXObject") && !window.ActiveXObject) {
// is IE11
}
Explanation: All versions of IE (except really old ones) have window.ActiveXObject property present. IE11, however hides this property from DOM and that property is now undefined. But the property itself is present within object, so checking for property presence returns true in all IE versions, but in IE11 it also returns false for second check.
And, finally, hasOwnProperty is called via Object because in IE8 (and I believe earlier) window is not an instanceof Object and does not have hasOwnProperty method.
Another method, using userAgent string:
var ua = window.navigator.userAgent;
var versionSplit = /[\/\.]/i;
var versionRe = /(Version)\/([\w.\/]+)/i; // match for browser version
var operaRe = /(Opera|OPR)[\/ ]([\w.\/]+)/i;
var ieRe = /(?:(MSIE) |(Trident)\/.+rv:)([\w.]+)/i; // must not contain 'Opera'
var match = ua.match(operaRe) || ua.match(ieRe);
if (!match) {
return false;
}
if (Array.prototype.filter) {
match = match.filter(function(item) {
return (item != null);
});
} else {
// Hello, IE8!
for (var j = 0; j < match.length; j++) {
var matchGroup = match[j];
if (matchGroup == null || matchGroup == '') {
match.splice(j, 1);
j--;
}
}
}
var name = match[1].replace('Trident', 'MSIE').replace('OPR', 'Opera');
var versionMatch = ua.match(versionRe) || match;
var version = versionMatch[2].split(versionSplit);
This will detect any version of IE if its userAgent string was not spoofed.
There very rare cases when you actually need to use browser detection as described above. In most cases feature detection approach is preferable.
isIE11 = !!window.MSStream;
if(isIE11){
/* Something */
}
Use !(window.ActiveXObject) && "ActiveXObject" in window to detect IE11 explicitly.
To detect any IE version, use window.ActiveXObject || "ActiveXObject" in window instead.
As already stated - dont do browser detection, rather do feature detection. However as I see your script is an older version of a script the circulates around here.
This is the updated version that detects IE 11 aswel:
function getInternetExplorerVersion()
{
var rv = -1;
if (navigator.appName == 'Microsoft Internet Explorer')
{
var ua = navigator.userAgent;
var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
if (re.exec(ua) != null)
rv = parseFloat( RegExp.$1 );
}
else if (navigator.appName == 'Netscape')
{
var ua = navigator.userAgent;
var re = new RegExp("Trident/.*rv:([0-9]{1,}[\.0-9]{0,})");
if (re.exec(ua) != null)
rv = parseFloat( RegExp.$1 );
}
return rv;
}
Is better for you if you avoid browser detection; if you need it here is a good explain from MS team:
In rare cases, it may be necessary to uniquely identify IE11 Preview. Use the Trident token to do so
User-agent string changes
For many legacy websites, some of the most
visible updates for IE11 Preview involve the user-agent string. Here's
what's reported for IE11 Preview on Windows 8.1 Preview: JavaScript
Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko
As with previous versions of Internet Explorer, portions of user-agent
string vary according to the environment. Here's the string for IE11
Preview on Windows 7: JavaScript
Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko
If you compare these strings to the ones reported by earlier versions
of Internet Explorer, you'll find the following changes: The
compatible ("compatible") and browser ("MSIE") tokens have been
removed. The "like Gecko" token has been added (for consistency with
other browsers). The version of the browser is now reported by a new
revision ("rv") token. These changes help prevent IE11 Preview from
being (incorrectly) identified as an earlier version. In general, you
should avoid detecting specific browsers or browser versions. The
assumptions underlying such tests tend to lead to false positive
results when browsers are updated. Instead, detect features as you
need them and use progressive enhancement to provide simplified
experiences for browsers or devices that do not support the features
you need. In rare cases, it may be necessary to uniquely identify IE11
Preview. Use the Trident token to do so
Link: http://msdn.microsoft.com/en-us/library/ie/bg182625(v=vs.85).aspx
More easy and efficient code and detect all versions of IE/Edge:
if(navigator.appVersion.indexOf("MSIE") != -1 || navigator.appVersion.indexOf("Trident") != -1 || navigator.appVersion.indexOf("Edge") != -1){
// is IE
}
I used the following code recently to detect IE in general and it worked just fine for IE 11 as well
var bs = document.body.style, isIE=false;
if ('msTransition' in bs) {
isIE = true;
}
The idea is to look for vedor prefix.
The 'use feature detection' mantra mystifies me. When you hit a bug, how can you determine what 'feature' is the culprit? Take for example this bit of code:
$('input[name^=qty]').keyup(function(e) {
if (this.value.match(/[^0-9\/]*/g)) {
this.value = this.value.replace(/[^0-9\/]/g, '')
}
});
It removes non-numeric chars from the input field as the user types. Works in FF, Chrome, and Safari. Does not work in ANY version of IE (up to 11, at least): any subsequent bindings on the input field will fail.
feature detect, feature detect, feature detect
<script>
if (!('querySelector' in document) //this should work in ie 9+
|| !('localStorage' in window) //ie 8+
|| !('addEventListener' in window) //ie 8 + (I think)
|| !('matchMedia' in window)) {//ie 10+
//do your redirect here
}
</script>
DO NOT DO BROWSER DETECTION! It will break, and it will cause you problems.
IE11 has a completely different User Agent string to previous IE versions; it not longer includes the "MSIE" text. This is why your detection code doesn't work.
It's important to note here that the reason they did this was deliberate. They wanted to break browser detection scripts like this.
It is possible to change your code to work with IE11, but I strongly recommend not doing this, as you'll probably have the same issue all over again when IE12 comes out.
So why did they want to break browser detection scripts? Simple: Because IE11 does not have the bugs of previous versions, and it has a lot of new features. So if you're doing browser detection because IE has certain bugs or missing features and you've got code to fix those issues based on the browser detect, then that code might actually cause worse problems in IE11 where the fixes aren't needed.
IE11 has broken your script, but the same logic applies to all browsers and all versions; detecting the browser and version is almost always the wrong thing to do.
If there are specific features that you want to support, but are missing in older IE versions (or other older browsers), don't use browser detection to work it out; you should use feature detection instead.
Feature detection means checking the browser to see whether it supports the particular features you want to use. The most common way of doing this is to use the Modernizr library. The docs on their site will guide you through setting it up.
There are a few bugs in older IE versions which are hard to detect, and for these few cases, it is valid to use browser detection as a last resort, but these cases are really only for IE6 and earlier. Maybe occasionally for IE7. But you've stated in the question that you're only looking at IE8 and later, so that should not apply.
Stick with feature detection; it's more reliable, better practice, and won't break suddenly when a new browser version is released.
Related
I didn't notice it in Modernizr's documentation but I imagine you create a menu element then check if it exists? My only concern is that the browser may support that but not type context. Any ideas? Thanks.
I have come up with a rather shoddy solution that returns true for Firefox as far as I can tell then returns false for Chrome, IE and Opera. Check it out:
// Detect context menu support.
function contextMenuSupported() {
var oMenu = document.createElement("menu");
// Kind of backwards but seems to work.
if (oMenu.type == "list")
return true;
return false;
}
Let me know if that just horrifies you. It seems when a menu element is created with a browser that supports it, certain attributes are intrinsically defined.
I have a Javascript function that calculates a value and re-inserts the value into a <td> while also injecting the value into a hidden <input>.
This is my function:
$("input[name^='policies']:checkbox").change(function() {
var el = $(this);
if (el.is(":checked")) {
no_policies++;
}
if (el.is(":not(:checked)")) {
no_policies--;
}
subscription = no_policies*policy_cost;
first_payment = Math.ceil(subscription+no_policies*(policy_cost/days_month)*days_left).toFixed(2);
alert(first_payment);
$("td#first_payment").text("R "+first_payment);
$("input#first_payment_txt").val(first_payment);
$("td#subscription").text("R "+subscription.toFixed(2));
});
Everything works on IE8 up until this statement:
first_payment = Math.ceil(subscription+no_policies*(policy_cost/days_month)*days_left).toFixed(2);
I suspect IE8 is having trouble with Math.ceil, is that true? Also, is there any other function/method I can use to circumvent this?
Thanks in advance.
Answer is yes to both your questions:
Math.ceil()
Math.round()
Supported in the following document
modes: Quirks, Internet Explorer 6
standards, Internet Explorer 7
standards, Internet Explorer 8
standards, Internet Explorer 9
standards.
See also general table of Javascript compatibility for different IE versions:
Seems like microsoft supports Math.ceil on all versions beginning from ie6 (msdn), maybe one of the variables use is undefined or you devide by 0 or one of the variables is not a number so the result cannot be ceiled/rounded.
IE8 actually has a fairly good debugger. I recommend hitting F12 to open it, then going to the Script tab and selecting the Start Debugging button. This will let you set breakpoints along the script, letting it stop and wait for you to analyze variables as it executes at your own pace. As Adriano mentions in his comment, it's most likely an issue with one of your variables.
I want to determine whether the browser of the client machines is Opera using JavaScript, how to do that?
Now that Opera uses the Chrome rendering engine, the accepted solution no longer works.
The User Agent string shows up like this:
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.52 Safari/537.36 OPR/15.0.1147.132
The only identifier for Opera is the OPR part.
Here's the code I use, which should match the old Opera or the new Opera. It makes the Opera var a boolean value (true or false):
var Opera = (navigator.userAgent.match(/Opera|OPR\//) ? true : false);
if(window.opera){
//do stuffs, for example
alert(opera.version()); //10.10
}
No kidding, there is an object opera in opera browser.
You may think, object opera is overridable, but navigator is overridable too.
UPDATE:
To get more accurate result, you could do like
if (window.opera && opera.toString() == "[object Opera]"){
//do stuffs, tested on opera 10.10
}
And I noticed, Opera have both addEventListener and attachEvent, so there is also another way like
if (window.addEventListener && window.attachEvent){
//do stuffs, tested on opera 10.10
}
The above answers no longer work in the new Opera 30. Since Opera now use Chromium. Please use the below:
var isChromium = window.chrome,
isOpera = window.navigator.userAgent.indexOf("OPR") > -1 || window.navigator.userAgent.indexOf("Opera") > -1;
if(isChromium !== null && isOpera == true) {
// is Opera (chromium)
} else {
// not Opera (chromium)
}
The new Opera 30 release now fully uses Chromium and also changed their userAgent to OPR
In Prototype.js, we use this inference:
var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]';
This essentially checks that window.opera object exists and its internal [[Class]] value is "Opera". This is a more solid test than just checking for window.opera existence, since there's much less chance of some unrelated global opera variable getting in the way and resulting in false positives.
Speaking of unrelated global variable, remember that in MSHTML DOM, for example, elements can be resolved by id/name globally; this means that presence of something like <a name="opera" href="...">foo</a> in a markup will result in window.opera referencing that anchor element. There's your false positive...
In other words, test [[Class]] value, not just existence.
And of course always think twice before sniffing for browser. Oftentimes there are better ways to solve a problem ;)
P.S. There's a chance of future versions of Opera changing [[Class]] of window.opera, but that seems to be unlikely.
The navigator object contains all the info you need. This should do:
navigator.userAgent.indexOf("Opera");
do you mind using jQuery?
then you can use jQuery.browser (see documnentation)
But the jQuery-guys recommend not to use this.
We recommend against using this
property, please try to use feature
detection instead (see jQuery.support)
Edit:
For Mootools: use window.opera (see documentation)
I've been searching for this for a couple of days now and so far, the best I can come up with is checking the list below. I really don't like to check for support based on User-Agent, especially since it can be spoofed. I've also heard of at least one instance where the list below is incorrect (noted below).
Is Internet Explorer?
Is WebKit? (But I've read that mobile Safari doesn't support it)
Is Opera?
Is Gecko and version >= 1.9? (meaning Firefox 3 or later)
Is there a better method based on testing for support directly via JavaScript, or is this pretty much the only way to test for support?
var canEditContent= 'contentEditable' in document.body;
The best way to check for a certain feature is to actually test for that feature on an element that you know should support it, like this:
if(element.contentEditable != null)
// then it's supported
or
if(typeof(element.contentEditable) != 'undefined')
// same thing.. but with typeof you can be more specific about the type of property you need to find
The best solution for my scenario (similar to yours) I came up with is below. It's not probably bulletproof, but covers most of the situations:
var ua = navigator.userAgent;
var android_version = ua.match(/Android ([0-9\.]+)/);
var div = document.createElement("DIV");
if( typeof(div.contentEditable) == 'undefined' ||
(/(iPhone|iPod|iPad)/i.test(ua) && /OS [1-4]_\d like Mac OS X/i.test(ua)) ||
(android_version!=null && parseFloat(android_version[1])<3 ) ||
(/(Opera Mobi)/i.test(ua))
) {
// doesn't support contenteditable
} else {
// supports contenteditable
}
You can test it out in this jsFiddle.
Notice: Depending on your needs and purpose, you might need to detect IE version as well, because it's support of contenteditable is ... "not ideal" :-) Most of the pains is dealt by super library Rangy.js.
bobince's answer works for the most part but, as has been said, you will need user agent sniffing to exclude iOS and Android versions that don't bring up the software keyboard. I'm currently using something like this:
function isContentEditable() {
var canEditContent = 'contentEditable' in document.body;
if (canEditContent) {
var webkit = navigator.userAgent.match(/(?:iPad|iPhone|Android).* AppleWebKit\/([^ ]+)/);
if (webkit && parseInt(webkit[1]) < 534) {
return false;
}
}
return canEditContent;
}
This should stop older iOS and Android devices from returning true. It still has one problem though: physical keyboards. If, for example, a device is running Android 2.3 but has a physical keyboard then the user will be able to use contentEditable but this function will return false. Physical keyboards are quite rare though.
More commonly, on some devices it may be possible for the user to bring up the on screen keyboard by pressing and holding the menu button. Obviously this isn't really something you should expect your users to know about.
You could mitigate these issues slightly by having some way for the user to manually override the sniffing part of the detection script. You could implement this in the isContentEditable function by adding an override check to "if (canEditContent)". However, Implementing the UI for this might present more of a challenge ;).
I've got some javascript code that applies an alpha transparency. Before it does that it attempts to detect what type of transparency the browser supports and stores that in a variable for use later. Here's what the code looks like:
// figure out the browser support for opacity
if (typeof br.backImg.style.opacity != 'undefined')
opacityType = 'opacity';
else if (typeof br.backImg.filters == 'object')
opacityType = 'filter';
else
opacityType = 'none';
For Firefox and Safari, the first condition is true, for IE7 the second condition is true, but for IE6 it falls to the last condition. Why would IE6 not have a filters object? Is there a better way of detecting this?
In IE7 it is filters and in IE6 it is filter.
The code below returns:
'opacity' if style.opacity is supported
'filter' for MS filter ( IE < 7 )
'filters' for MS filters ( IE7 )
'none' for everything else
.
var opacityType=(
(typeof o.style.opacity !== 'undefined') ? 'opacity' :
/*#cc_on #if (#_jscript)
(typeof o.filters === 'object') ? 'filters' :
(typeof o.filter === 'string') ? 'filter' :
#end #*/
'none'
);
The #cc_on, #if and #_jscript are used in a conditional comment that only IE supports.
I have tested this on FF3, IE6, IE7, Opera9 and Chrome 1 but not on IE4,5,or 8.
According to quirksmode MS has changed the CSS from filter to -ms-filter so I don't know what result you get with IE8.
According to mozilla opacity has been supported since FF 0.9, Opera 9 and Safari 1.2 and filter since IE4.
I don't like to do browser sniffing, but sometimes it is necessary and conditional comments make it so much easier to handle specific IE things.
What you understand as filters is called opacity. Real filters are a proprietary IE extension which enables opacity amongst many other things for that browser.
Try this article for cross-browser transparency techniques.
The JS equivalents are exactly the same as described: style.opacity or style.filter. More likely problem is that your doctype is transitional and/or the item you're trying to make transparent doesn't have the magical hasLayout