Discover Quirks Mode in IE - javascript

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.

Related

Detect IE 10 among conditional comments for IE 7+ detection

I have a page with form for user registration. I wrapped it with <!--[if IE]> ... <![endif]--> to show it only in IE. And corresponding error is shown for other browsers: <![if !IE]>...<![endif]>.
But this doesn't fully work with IE 10. One can use java-script to determine IE 10, like:
<script type="text/javascript">
var pattern = /MSIE\s([\d]+)/;
var ua = navigator.userAgent;
var matched = ua.match(pattern);
if (matched) {
alert("IE 10");
}
</script>
But how can I bind it with html block I use for IE7+?
Updated
It needs for using the IX509 Windows interface which demands IE usage because it is COM object (I'm not sure, but it seems it uses ActiveX for it), otherwise strange errors will appear on a page when IX509 is used.
For ActiveX support, just check that the ActiveXObject exists in JS:
if(typeof window.ActiveXObject != "undefined")
Or more specifically:
if(typeof window.ActiveXObject == "function")
If you're confident that scoping is not an issue in your script and don't want the window., variables are of course automatically fetched from the window object, so you can shorten the code to:
if(typeof ActiveXObject != "undefined")
Though it should only be used with understanding of potential consequences
Use feature detection, not browser detection.
You can detect whether the browser supports ActiveX with the following simple line of code:
if(typeof window.ActiveXObject != "undefined") { ..... }
Why?
Browser detection is fragile -- newer versions of IE may not be picked up by your detection code, resulting in your site breaking. In fact this is exactly what's happened here. And you'd probably have the same issue all over again with IE11. The above feature detection script will work correctly in all browsers and all versions.
Not all IE installations have ActiveX available. If you detect IE and then assume it supports ActiveX, your site will break badly for those that don't have it. Again, using feature detection instead will avoid this issue.
I improved the approach I tried at first.
First of all error page is wrapped with the following <div>:
<div id="not_ie" style="display:none">
IE form is also wrapped with <div>:
<div id="ie" style="display:none">
And the following js makes form or error visible depending on browser type:
<script type="text/javascript">
var pattern = /MSIE\s([\d]+)/;
var ua = navigator.userAgent;
var matched = ua.match(pattern);
if (matched) {
var elem = document.getElementById("ie");
elem.style.display = "inline";
} else {
var elem = document.getElementById("not_ie");
elem.style.display = "inline";
}
</script>
There's no need in use of conditional comments, determining of ActiveX or version-specific feature of IE.

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
}
});

"'localStorage' is null or not an object" Error in IE8

I have this string which i'm trying to store and get to localStorage, and retrieve from it so it could show.
Here's my code:
var datas = new Array;
if (navigator.appName !== 'Microsoft Internet Explorer'){
var qsVal = document.getElementsByClassName("val");
}
else{
var qsVal = document.querySelectorAll('.val');
}
if (navigator.appName !== 'Microsoft Internet Explorer'){
var qsKey = document.getElementsByClassName("key");
}
else{
var qsKey = document.querySelectorAll('.key');
}
var storedPlays;
var stuff = document.getElementById("stuff");
function pushArray(){
for (var i=0, len = qsVal.length; i < len; i++){
thisValue = qsVal[i].value;
thisKey = qsKey[i].value;
datas.push([thisValue,thisKey]);
}
localStorage.setItem('datas', JSON.stringify(datas));
}
function showStuff(){
storedPlays = JSON.parse(localStorage.getItem('datas'));
document.getElementById("stuff").innerHTML = storedPlays;
}
It works great with FF and Chrome, but IE8 returns "'localStorage' is null or not an object" when I call 'showStuff'.
What's interesting is that it doesn't give me an error when I call 'pushArray', which uses 'localStorage' as well.
Iv'e also tried using "window.localStorage" instead of just "localStorage", it returned the same error...
IE8 is supposed to support localStorage, according to Microsoft and W3, so does anyone has any clue as to where the problem is?
Thanks a million!
EDIT - This is a jsfiddle for the code. for some reason, it doesn't work that good but just to give you a feel of the code...
As per my understanding IE8 give storage to only valid domains. Try placing your example in some Web-server it should resolve the issue.
I faced the same issue when I tested it as an individual file but when i placed it in a server(Tomcat in my case) it just worked fine.
Check if you are actually in IE 8 mode - as opposed to quirks or IE 7 mode. Fastest way to do this is hit F12 to bring up the dev tools, and the browser mode is listed on the upper right of that tab.
I would give using window.localStorage as shot. See Introduction to Web Storage for IE
Can you open the developer tools in IE and check that typeof json. stringify and json.parse are functions and also localstorage. I am not sure whether native JSON exist on IE.
Also why are you setting the object inside the loop, shouldnt it be outside it?
[Edit]
Added this fiddle for your code jsfiddle.net/yrhdN/2 and everything seems to work fine. I have tested in IE9 under IE8 compatibility mode)
[Edit]
One more thing about this code, it seems innerHtml in showStuff() doesn't work with a paragraph. Changing the html from p to div and using innerText makes things a little better:
<div id="stuff">
</div>
function showStuff(){
var storedPlays = JSON.parse(localStorage.getItem('datas'));
document.getElementById("stuff").innerText = storedPlays;
}
This seems to happen only in IE. Here is an updated fiddle: http://jsfiddle.net/yrhdN/7/
Try this also if you do not wish any local server application to shoot the webpage.
Look for the code in your script : window['localStorage'] !== null
change it to : window['localStorage'] != null
It worked in my case.

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

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});
})();

Why does CSS3Pie + Prototype 1.6.1 crash Internet Explorer 8

I'm trying to understand why Css3Pie used in conjunction with Prototype 1.6.1 crashes Internet Explorer 8. Why is this happening?
Relevant information
CSS3Pie [source code] is an Internet Explorer behavior (htc) that adds support for CSS3 properties like border-radius, gradients, etc.
The crash only happens in IE8, not IE7 or earlier.
The crash only happens in Prototype 1.6.1 [source code], not Prototype 1.6.0.x
The crash happens immediately on page load, I'm not even able to interact with the page.
The developer is aware of the issue but since he believes it is a Prototype issue (it may be), he may not be eager to fix it. There is both a forum post and GitHub bug report, but neither add much information.
This IE8 crash, which appears to have been fixed in a recent Windows update, was triggered by Prototype's tinkering with DOM object prototypes followed by the application of the CSS3Pie behavior. In Protoype 1.6.1, it can be worked around by setting ElementExtensions and SpecificElementExtensions to false on the Prototype.BrowserFeatures object and modifying the checkDeficiency function to return true immediately.
It's a good start, but then it stops working under other browsers (ie. firefox, chrome). Instead you should add at the beginning of each function (ElementExtensions, SpecificElementExtensions, checkDeficiency) a check for IE 8 then return false for the Extensions anonymous functions and return true for the checkDeficiency function.
ElementExtensions: (function() {
if (isIE8) return false;
...
SpecificElementExtensions: (function() {
if (isIE8) return false;
...
function checkDeficiency(tagName) {
if (isIE8) return true;
...
var isIE8 = (function(){
return ((navigator.userAgent.indexOf('MSIE')!=-1) && (document.documentMode==8));
})();

Categories