As many already posted in other questions (also in jQuery documentation), the old jQuery.browser.version is deprecated and works only in jquery1.3.
Do you know another simple way to detect it, that I can include in my code before:
function handleInfoDivPopupVisibility(dynamicEleId, staticEleId){
var parentContainer = $('headerSummaryContainer');
var dynamicEle = $(dynamicEleId);
var staticEle = $(staticEleId);
if(isIE() && parentContainer){
if (jQuery.browser.version != 10) { // I need to find a way to detect if it's IE10 here.
parentContainer.style.overflow = 'visible';
}
}
dynamicEle ? dynamicEle.style.display = '' : '';
if(dynamicEle && staticEle)
gui_positionBelow(dynamicEle, staticEle);
}
Before you say it's duplicated question of this or this, I'd like to reinforce that I don't want to use css hacks. Is there a way to detect it just as simple as I could do before?
if (jQuery.browser.version != 10) {...
In general it's a bad idea to check for browser version, it's considered a better practice to check for browser features. But if you're sure what you're doing:
function getIEVersion(){
var agent = navigator.userAgent;
var reg = /MSIE\s?(\d+)(?:\.(\d+))?/i;
var matches = agent.match(reg);
if (matches != null) {
return { major: matches[1], minor: matches[2] };
}
return { major: "-1", minor: "-1" };
}
var ie_version = getIEVersion();
var is_ie10 = ie_version.major == 10;
We have the following code in production, so it works and well-tested.
And yes, we did have a need to detect IE10, not just a particular feature that exists in IE10 but not in earlier versions.
Internet Explorer has the feature of Conditional Compilation (http://www.javascriptkit.com/javatutors/conditionalcompile.shtml). You can use this:
var isIE10 = false;
/*#cc_on
if (/^10/.test(#_jscript_version)) {
isIE10 = true;
}
#*/
alert(isIE10);
DEMO: http://jsfiddle.net/X3Rvz/1/
You can put this before all your JavaScript code, and from then on just reference isIE10.
The conditional compilation won't run in non-IE, so isIE10 will still be false. And #_jscript_version will only start with 10 in IE 10.
Conditional Comments aren't supported in IE 10, and the User-Agent string can be spoofed.
Since minification usually removes comments, you can use eval or Function to find out in a similar fashion:
var isIE10 = false;
if (Function('/*#cc_on return /^10/.test(#_jscript_version) #*/')()) {
isIE10 = true;
}
DEMO: http://jsfiddle.net/wauGa/2/
UPDATE:
To still avoid minification of comments but also combine detecting any version, you can use something like:
var IE = (function () {
"use strict";
var ret, isTheBrowser,
actualVersion,
jscriptMap, jscriptVersion;
isTheBrowser = false;
jscriptMap = {
"5.5": "5.5",
"5.6": "6",
"5.7": "7",
"5.8": "8",
"9": "9",
"10": "10"
};
jscriptVersion = new Function("/*#cc_on return #_jscript_version; #*/")();
if (jscriptVersion !== undefined) {
isTheBrowser = true;
actualVersion = jscriptMap[jscriptVersion];
}
ret = {
isTheBrowser: isTheBrowser,
actualVersion: actualVersion
};
return ret;
}());
And access the properties like IE.isTheBrowser and IE.actualVersion (which is translated from internal values of JScript versions).
The jQuery.browser.version still works but you have to include the jquery-migrate plugin.
http://api.jquery.com/jQuery.browser/
https://github.com/jquery/jquery-migrate/#readme
The IE10 User-Agent String says
However if your site is still using user-agent sniffing, then increasing the “MSIE” token to “10.0” is particularly noteworthy. Why? Because it adds an extra digit to the string value of the token. Most sites will handle this effortlessly, but some will process the extra digit incorrectly, causing them to identify IE10 as IE1.
To help illustrate, here’s a regular expression that only captures the first digit of the “MSIE” token’s value:
// INCORRECT: will report IE10 version in capture 1 as "1"
var matchIE = /MSIE\s(\d)/;
And here’s one that captures the full value of the “MSIE” token:
// Correct: will report IE10 version in capture 1 as "10.0"
var matchIE = /MSIE\s([\d.]+)/
Here is a one line solution to detect IE 10
var IE10 = navigator.userAgent.toString().toLowerCase().indexOf("trident/6")>-1;
and for more information on other version and browsers please refer this Link of Browser Detection
I Found myself having a issue (border radius on frameset with legend) with IE 9 through 11 (did not check IE 12)
MSIE is no long user agent in IE 11 and the appName is Mozilla, however trident is in there
I managed to extract the trident version # and detect it
if(navigator.appVersion.indexOf('Trident/')>-1){// Begin stupid IE crap
var IE=navigator.appVersion;
IE=IE.slice(IE.indexOf('Trident/')+8);
IE=IE.slice(0,IE.indexOf(';'));
IE=Number(IE);
if(IE>=5&&IE<=7) // IE 9 through IE 11
document.body.className='ie';
}
Related
In a project I'm working on, I have a textbox where the user has to input his name. To avoid the user from entering numbers I used the jquery.limitkeypress.js library written by Brian Jaeger and every thing was working perfectly until I tested the website in Internet Explorer 10. In IE10, you can input all the letters you want, and you can not input number or weird symbols just as I wanted but when I type a space and then a letter, I see the letter print right to the space and then the space disappearing and the latter shifting to the left. The weird thing is that if I wait like 30 seconds after typing the space to type the letter it works fine.
jquery.limitkeypress.js has some issue with ie, I recommend you to use a more powerful library.
http://github.com/RobinHerbots/jquery.inputmask
With this library you can use something like this:
$(".numbers").inputmask('Regex', {
mask: "9",
repeat: 11,
placeholder: ""
});
It works perfectly on ie. :)
Sorry i have not updated that plugin in a few years but...
jquery.limitkeypress now works with IE9+ there was an issue with how the selection was determined.
IE11 killed support for their document.selection but they kept the document.setSelectionRange which i was using to test what browser was being used...
IE9 enabled document.selectionStart and document.selectionEnd so i now check directly what browser version of IE peoples are using...
I added this to check for IE version:
var ie = (function(){
var undef,
v = 3,
div = document.createElement('div'),
all = div.getElementsByTagName('i');
while (
div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->',
all[0]
);
return v > 4 ? v : undef;
}());
So my selection functions now look like this:
function getSelectionStart(o) {
if (ie < 9) {
var r = document.selection.createRange().duplicate()
r.moveEnd('character', o.value.length)
if (r.text == '') return o.value.length
return o.value.lastIndexOf(r.text)
} else return o.selectionStart
}
function getSelectionEnd(o) {
if (ie < 9) {
var r = document.selection.createRange().duplicate()
r.moveStart('character', -o.value.length)
return r.text.length
} else return o.selectionEnd
}
var id = data.rslt;
var element = id.attr("crawlLocation");
if (element.indexOf("\\") != -1){
var toSearch = element.substring(0,element.lastIndexOf("\\"));
toSearch = "\"" + toSearch + "\"";
}
var stringContent = getInnerHTML('selectedCustodiansForIngestDiv');
if(stringContent.indexOf(toSearch) == -1){
//This loop works fine on Firefox but not in IE8
}
function getInnerHTML(elmtId) {
var innerHTML = "";
if ($gElem(elmtId) != null) {
innerHTML = document.getElementById(elmtId).innerHTML;
}
return innerHTML;
}
In the above code, the if condition with the indexOf method is not working as expected with IE8, but works fine with other browsers.
In IE8, even if the content in toSearch is found in the string stringContent, it goes inside the loop.
I am not sure whether the problem is with indexOf method or somewhere else in my code. Let me know a way to fix this! Thanks!
UPDATE
I just noticed on debugging that in IE, the toSearch variable is appearing as "\"D:\company\"" instead of "D:\company"(In mozilla and other browsers).
Any idea to overcome this?
As you can see on this compatibility table it's not available in IE8.
You can take a RegEx to account or see the fallbacks from MDN for:
indexOf
lastIndexOf
I've downloaded Yahoo JavaScript Uglify (yuglify) from https://github.com/yui/yuglify and I intent to use it for JS and CSS compression on some PHP projects hosted on a apache server. Tried to minify a file with these original contents:
var _cmFrameList = new Array (); // a pool of reusable iframes
var _cmFrameListSize = 0; // keep track of the actual size
var _cmFrameIDCount = 0; // keep track of the frame id
var _cmFrameMasking = true; // use the frame masking
// disable iframe masking for IE7
/*#cc_on
#if (#_jscript_version >= 5.6)
if (_cmFrameMasking)
{
var v = navigator.appVersion;
var i = v.indexOf ("MSIE ");
if (i >= 0)
{
if (parseInt (navigator.appVersion.substring (i + 5)) >= 7)
_cmFrameMasking = false;
}
}
#end
#*/
var _cmClicked = false; // for onClick
But got this instead:
var _cmFrameList=new Array,_cmFrameListSize=0,_cmFrameIDCount=0,_cmFrameMasking=!0,_cmClicked=!1
In the contents of the original file, there's some conditional compilation code that's needed to work on older IE browsers (commented lines starting with #cc_on, #if, #end, etc). It seems that yuglify is treating these conditional compilation lines as simple comments, and as such, is removing all of it.
By curiosity, I've tested yuicompressor on this same file too ( https://github.com/yui/yuicompressor/downloads ), and it seems that all conditional compilation code is intact. Even the linebreaks are still there:
var _cmFrameList=new Array();var _cmFrameListSize=0;var _cmFrameIDCount=0;var _cmFrameMasking=true;
/*#cc_on
#if (#_jscript_version >= 5.6)
if (_cmFrameMasking)
{
var v = navigator.appVersion;
var i = v.indexOf ("MSIE ");
if (i >= 0)
{
if (parseInt (navigator.appVersion.substring (i + 5)) >= 7)
_cmFrameMasking = false;
}
}
#end
#*/
var _cmClicked=false;
Older IE browsers gets garbled without those conditional compilation lines. Is it possible to use yuglify without removing it?
Found a way to solve it, by using a little workaround with eval command.
Firtly, I created these global variables:
var is_IE_browser = eval('/*#cc_on !#*/false');
var jscript_version = (is_IE_browser) ? eval("/*#cc_on #_jscript_version #*/") : (0);
var IE_version = (is_IE_browser) ? (get_IE_version()) : (0);
And then, I created this function:
function get_IE_version(){
var IE_version;
if(jscript_version == 5.6 || (jscript_version == 5.7 && navigator.userAgent.toLowerCase().indexOf("msie 6.") != -1)) {
IE_version = 6;
} else if(jscript_version == 5.7){
IE_version = 7;
} else if(jscript_version == 5.8){
IE_version = 8;
} else if(jscript_version == 9){
IE_version = 9;
} else if(jscript_version == 10){
IE_version = 10;
} else {
IE_version = 0;
}
return IE_version;
}
By doing this, now I can replace all Conditional Compilation code (cc_on) with a few conditions using the variables above.
The variable "is_IE_browser" will return true if browser is IE, and false if not.
The variable "IE_version" will return IE version number if browser is IE, and zero if not.
Using this code, I can detect reliably most IE browsers (except IE6, that needs a little search on browser user agent data, and it's vulnerable to browser sniffing, but I can live with it).
This way, I can detect older browsers fine, and continue using yuglify without having my JS file damaged.
I have a JavaScript from this source in a comment of a blog: frogsbrain
It's a string formatter, and it works fine in Firefox, Google Chrome, Opera and Safari.
Only problem is in IE, where the script does no replacement at all. The output in both test cases in IE is only 'hello', nothing more.
Please help me to get this script working in IE also, because I'm not the Javascript guru and I just don't know where to start searching for the problem.
I'll post the script here for convenience. All credits go to Terence Honles for the script so far.
// usage:
// 'hello {0}'.format('world');
// ==> 'hello world'
// 'hello {name}, the answer is {answer}.'.format({answer:'42', name:'world'});
// ==> 'hello world, the answer is 42.'
String.prototype.format = function() {
var pattern = /({?){([^}]+)}(}?)/g;
var args = arguments;
if (args.length == 1) {
if (typeof args[0] == 'object' && args[0].constructor != String) {
args = args[0];
}
}
var split = this.split(pattern);
var sub = new Array();
var i = 0;
for (;i < split.length; i+=4) {
sub.push(split[i]);
if (split.length > i+3) {
if (split[i+1] == '{' && split[i+3] == '}')
sub.push(split[i+1], split[i+2], split[i+3]);
else {
sub.push(split[i+1], args[split[i+2]], split[i+3]);
}
}
}
return sub.join('')
}
I think the issue is with this.
var pattern = /({?){([^}]+)}(}?)/g;
var split = this.split(pattern);
Javascript's regex split function act different in IE than other browser.
Please take a look my other post in SO
var split = this.split(pattern);
string.split(regexp) is broken in many ways on IE (JScript) and is generally best avoided. In particular:
it does not include match groups in the output array
it omits empty strings
alert('abbc'.split(/(b)/)) // a,c
It would seem simpler to use replace rather than split:
String.prototype.format= function(replacements) {
return this.replace(String.prototype.format.pattern, function(all, name) {
return name in replacements? replacements[name] : all;
});
}
String.prototype.format.pattern= /{?{([^{}]+)}}?/g;
In some existing code there is a test to see if the user is running IE, by checking if the object Browser.Engine.trident is defined and returns true.
But how can I determine if the user is running IE6 (or earlier) or IE7 (or later)?
The test is needed inside a JavaScript function so a conditional comment doesn't seem suitable.
From detecting Internet Explorer More Effectively at msdn:
function getInternetExplorerVersion()
// Returns the version of Internet Explorer or a -1
// (indicating the use of another browser).
{
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;
}
function checkVersion()
{
var msg = "You're not using Internet Explorer.";
var ver = getInternetExplorerVersion();
if ( ver > -1 )
{
if ( ver >= 6.0 )
msg = "You're using a recent copy of Internet Explorer."
else
msg = "You should upgrade your copy of Internet Explorer.";
}
alert( msg );
}
If you really want to be sure you are using IE and a specific version then you could obviously use IE's conditional tags to only run certain code within IE. It's not really that pretty but at least you can be sure that it is really IE and not some spoofed version.
<script>
var isIE = false;
var version = -1;
</script>
<!--[if IE 6]>
<script>
isIE = true;
version = 6
</script>
<![endif]-->
<!--[if IE 7]>
<script>
isIE = true;
version = 7
</script>
<![endif]-->
It's pretty self explanatory. In IE6 isIE is true and version is 6, In IE7 isIE is true and version is 7 otherwise isIE is false and version is -1
Alternatively you could just roll your own solution using code plagarised from jQuery.
var userAgent = navigator.userAgent.toLowerCase();
var version = (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [])[1],
var isIE = /msie/.test( userAgent ) && !/opera/.test( userAgent ),
If you are already using jQuery in a pre-1.9 version AND you don't need to detect IE 11, you can do this:
if (jQuery.browser.msie == true) {
if (jQuery.browser.version == 7.0)
// .. do something for 7.0
else
// .. do something for < 7.0
}
The Navigator object contains all the information about the user's browser:
eg:
var browser=navigator.appName;
var b_version=navigator.appVersion;
var version=parseFloat(b_version);
See:
http://www.w3schools.com/js/js_browser.asp
If you are checking for a certain functionality, you should check for it directly, e.g. if (window.focus) {window.focus();} Browser detection is never reliable enough.
For more details on object vs browser detection, check out this article at Quirksmode.
On the other hand, if the feature you need IS the browser type and version, e.g. for statistical purposes, go with navigator.appName and navigator.appVersion. (Beware though - many less popular browsers masquerade themselves as MSIE 6 or 7, as certain sites block anything that's not IE on the premise that "all the modern browsers are IE, right?" (hint: not anymore).)
So IE8 compatibility view mode reports itself as IE7 even though it doesn't always behave the same. And for that, I give you this monster:
// IE8's "Compatibility mode" is anything but. Oh well, at least it doesn't take 40 lines of code to detect and work around it.
// Oh wait:
/*
* Author: Rob Reid
* CreateDate: 20-Mar-09
* Description: Little helper function to return details about IE 8 and its various compatibility settings either use as it is
* or incorporate into a browser object. Remember browser sniffing is not the best way to detect user-settings as spoofing is
* very common so use with caution.
*/
function IEVersion(){
var _n=navigator,_w=window,_d=document;
var version="NA";
var na=_n.userAgent;
var ieDocMode="NA";
var ie8BrowserMode="NA";
// Look for msie and make sure its not opera in disguise
if(/msie/i.test(na) && (!_w.opera)){
// also check for spoofers by checking known IE objects
if(_w.attachEvent && _w.ActiveXObject){
// Get version displayed in UA although if its IE 8 running in 7 or compat mode it will appear as 7
version = (na.match( /.+ie\s([\d.]+)/i ) || [])[1];
// Its IE 8 pretending to be IE 7 or in compat mode
if(parseInt(version)==7){
// documentMode is only supported in IE 8 so we know if its here its really IE 8
if(_d.documentMode){
version = 8; //reset? change if you need to
// IE in Compat mode will mention Trident in the useragent
if(/trident\/\d/i.test(na)){
ie8BrowserMode = "Compat Mode";
// if it doesn't then its running in IE 7 mode
}else{
ie8BrowserMode = "IE 7 Mode";
}
}
}else if(parseInt(version)==8){
// IE 8 will always have documentMode available
if(_d.documentMode){ ie8BrowserMode = "IE 8 Mode";}
}
// If we are in IE 8 (any mode) or previous versions of IE we check for the documentMode or compatMode for pre 8 versions
ieDocMode = (_d.documentMode) ? _d.documentMode : (_d.compatMode && _d.compatMode=="CSS1Compat") ? 7 : 5;//default to quirks mode IE5
}
}
return {
"UserAgent" : na,
"Version" : version,
"BrowserMode" : ie8BrowserMode,
"DocMode": ieDocMode
}
}
var ieVersion = IEVersion();
var IsIE8 = ieVersion.Version != "NA" && ieVersion.Version >= 8;
This is probably going to get voted down, because it's not directly answering the question, but... You should not be writing browser-specific code. There's very little you can't do while coding for most widely-accepted browsers.
EDIT: The only time I found it useful to have conditional comments was when I needed to include ie6.css or ie7.css.
Well... here is what I came up after thinking for a while. just wanted to find a simple solution.
if (navigator.appName == 'Microsoft Internet Explorer') {
// Take navigator appversion to an array & split it
var appVersion = navigator.appVersion.split(';');
// Get the part that you want from the above array
var verNumber = appVersion[1];
alert(verNumber);
}
It returns ex:- MSIE 10.0, MSIE 9.0, MSIE 8.0
further extend, if you want to check if it's "lower than" or "greater than" IE version, you can slightly modify
if (navigator.appName == 'Microsoft Internet Explorer') {
var appVersion = navigator.appVersion.split(';');
var verNumber = appVersion[1];
// Reaplce "MSIE " from the srting and parse it to integer value
var IEversion = parseInt(verNumber.replace('MSIE ', ''));
if(IEversion <= 9){
alert(verNumber);
}
}
got the base idea from w3schools, hope this will help some one... :D
This is the script I use and it seems to work well enough:
// Returns 0 if the browser is anything but IE
function getIEVersion() {
var ua = window.navigator.userAgent;
var ie = ua.indexOf("MSIE ");
return ((ie > 0) ? parseInt(ua.substring(ie+5, ua.indexOf(".", ie))) : 0);
}
Hope that helps someone...
This should give you more details than you'll want:
var agent = navigator.userAgent;
var msiePattern = /.*MSIE ((\d+).\d+).*/
if( msiePattern.test( agent ) ) {
var majorVersion = agent.replace(msiePattern,"$2");
var fullVersion = agent.replace(msiePattern,"$1");
var majorVersionInt = parseInt( majorVersion );
var fullVersionFloat = parseFloat( fullVersion );
}
As no-one seems to have said it yet:
The test is needed inside a JavaScript function so a conditional comment doesn't seem suitable.
You can easily put a conditional comment — a JScript conditional comment, not an HTML one — inside a function:
function something() {
var IE_WIN= false;
var IE_WIN_7PLUS= false;
/*#cc_on
#if (#_win32)
IE_WIN= true;
#if (#_jscript_version>=5.7)
IE_WIN_7PLUS = true;
#end
#end #*/
...
}
It's more typical to do the test once at global level though, and just check the stored flags thereafter.
CCs are more reliable than sifting through the mess that the User-Agent string has become these days. String matching methods on navigator.userAgent can misidentify spoofing browsers such as Opera.
Of course capability sniffing is much better for cross-browser code where it's possible, but for some cases — usually bug fix workarounds — you do need to identify IE specifically, and CCs are probably the best way to do that today.
<script>
alert("It is " + isIE());
//return ie number as int else return false
function isIE() {
var myNav = navigator.userAgent.toLowerCase();
if (myNav.indexOf('msie') != -1) //ie less than ie11 (6-10)
{
return parseInt(myNav.split('msie')[1]);
}
else
{
//Is the version more than ie11? Then return false else return ie int number
return (!!(myNav.match(/trident/) && !myNav.match(/msie/)) == false)?false : parseInt(myNav.split('rv:')[1].substring(0, 2));
}
}
</script>