Is it possible to configure the erb page to detect IE version and based on that select different compatibility tags, so it should work as:
if user IE=10 then
< meta http-equiv="X-UA-Compatible" content="IE=EmulateIE9" / >
else
Please don't propose other solutions as I need exactly the logic I described.
We have an application which doesn't work in IE10 and all the solutions we tried don't work except and only with IE=EmulateIE9 it works.
Does the application work in IE11 or Microsoft Edge? If not, then you could force all Microsoft browsers to emulate IE9 using <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE9">.
If you need to target IE10 specifically, then you should use feature detection, since IE10+ no longer supports conditional comments and user agent sniffing can be unreliable.
Here's a code snippet which identifies the browser by checking for version-specific CSS properties. It's a simplified version of a solution that I found here. I've tested it in IE9, 10, 11 and Microsoft Edge:
<!DOCTYPE html>
<html>
<head>
<title>Browser Detection</title>
</head>
<body>
<h1>Browser Detection</h1>
<h2 id="message"></h2>
<script>
var message = document.getElementById('message');
var browser = "Less than IE10 (or not IE at all)";
if (document.body.style['msTouchAction'] != undefined) {
browser = "IE10";
}
if (document.body.style['msTextCombineHorizontal'] != undefined) {
browser = "IE11 or higher";
}
message.innerHTML = browser;
</script>
</body>
</html>
The above snippet may not work for your purposes because the Javascript gets executed in the body, after the meta tags in the head have already been parsed.
I suppose you could trigger a page redirect for IE10+ browsers and add an argument to the URL, which would prevent the feature detection Javascript from executing the next time (you don't want to create an infinite loop). A quick example:
<script>
if (!document.location.search) {
if (document.body.style['msTouchAction'] != undefined) {
// Browser is IE10 or higher
window.location = "http://www.yoururl.com/?ie9mode";
}
}
</script>
An even better solution would be to store the result of the browser detection script in a session variable, so that you wouldn't need to append anything to the URL.
I hope this helps!
Related
We want to avoid problems with non-supported browsers in our svelte/sapper application.
1. Problem: Detect Internet Explorer
I want to warn users that our application written in Sapper/Svelte is not compatible with Internet Explorer. It can be simple plain-text message or redirect to some error page.
What I want in case of message is to stop execution of any further code after displaying warning message.
If redirect will be chosen then stopping execution is not needed.
Now I have this code
<head>
...
<!-- IE10+ will switch to IE9 behaviour and will respect IE HTML conditional tags -->
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE9">
...
</head>
<body>
<![if !IE]>
<div id='sapper'>%sapper.html%</div>
%sapper.scripts%
<![endif]>
<!--[if IE]>
<h1 style="color: #333; font-family: 'Arial'; font-size: 18px; padding: 24px 18px; text-align: center;">
We do not support Internet Explorer.
</h1>
<p style="font-size: 46px; text-align: center; padding: 12px 0;">:/</p>
<![endif]-->
</body>
in the template.html file. Will this be enough to detect all IE browsers (with old engine)?
2. Problem: Detect any other missing feature on run-time
I was thinking that detecting the IE may not be enough for proper browser compatibility detection. Is there some universal Svelte compatibility detection function that I can use?
I still want some last-resort block of code that if application will crush in runtime on SOME not supported feature (local storage, spread operator, service worker, ...) than i want to display message or redirect user to error page.
UPDATE: I used IE conditional tags with meta tag. If there will be requirement to better detect browser features I would implement it in form of tests that would be performed during app initialisation.
The rollup sapper template includes support for "legacy mode". It's not documented anywhere but it creates separate javascript files for older browsers using babel. If you are using this ES6 syntax shouldn't cause problems, if babel is configured appropriately. Your site should still function without a service worker. For other features, such as local storage, I would test for specific features as required and try to fail gracefully.
If you are curious here is the code Sapper uses to detect legacy browsers and load the appropriate js files:
(function() {
try {
eval("async function x(){}");
var main = "${main}"
} catch (e) {
main = "${legacy_main}"
};
var s = document.createElement("script");
try {
new Function("if(0)import('')")();
s.src = main;
s.type = "module";
s.crossOrigin = "use-credentials";
} catch (e) {
s.src = "${req.baseUrl}/client/shimport#${build_info.shimport}.js";
s.setAttribute("data-main", main);
}
document.head.appendChild(s);
}());
You're using conditional comment to detect IE which is not supported by IE 10 and 11. If you want to detect all IE version, you could execute the function below at the beginning of the app:
var ua = window.navigator.userAgent;
var msie = ua.indexOf("MSIE ");
if (msie > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./)) // If Internet Explorer
{
// If you want to redirect
window.location.href = "http://www.example.com";
}
For the features, I don't find API in Svelte to detect them all. I think you can use JavaScript to detect the support of the features when you need.
I'm trying what should have been a simple operation: when a user clicks a link a modal window pops up that's populated with some appropriate data in a string. Here's the HTML for the window:
<!DOCTYPE HTML>
<html>
<head>
<title>Modal Display Window</title>
</head>
<body>
<div id="modal_display_block">REPLACE THIS</div>
</body>
</html>
And this is the Javascript function that calls and populates the window:
function displayCenterBlock(data) {
DispWin = window.open("modal_window.html", "", 'toolbar=no,status=no,width=300,height=300');
DispWin.onload = function() {
DispWin.document.getElementById('modal_display_block').innerHTML = data;
}
}
This works great in every browser I've tried except Internet Explorer. In IE the innerHTML does not get rewritten by the data. Is there some IE-specific trick or tweak I need to apply to get this working in that browser?
Many thanks in advance!
ON EDIT: I've discovered that if I move the element rewrite line out of the onload function it then works fine in IE but not in other browsers. It appears my options are to use some conditional code to rewrite at once for IE and to wait for page load for all other browsers, or to abandon the rewrite element approach and just use a document.write. I get from forum searches people like to discourage document.write but that's looking pretty appealing right now.
Okay, for better or worse this code achieves the goal and appears to work cross browser, even in IE.
DispWin = window.open("", "Display", 'toolbar=no,status=no,width=300,height=300');
DispWin.document.open();
DispWin.document.write(data);
DispWin.document.close();
DispWin.focus();
I get that document.write can re-write the whole page, and that is sometimes bad, but in this case that is exactly what I want: a single small page displaying only what was passed in the data argument. I can style it inline.
i create a javascript webapp based on Extjs 4.2. A lot of feature of this framework doesn't work correctly with IE8 (and i don't know the result with previous versions). I'm searching the more clean way to block the access of my web app using user agent like IE8 or lesser from displaying a message and avoid the login to the webapp.
Anytype of help is usefull
if( ! Ext.isIE6 || ! Ext.isIE7 ) {
yourapp.init();
} else {
//show the element that directs people to http://browsehappy.com/
}
I wouldn't block access, I would show a message that says features in this application may not function correctly. Denying access is bad. If you want easy IE8 detection checkout Conditionizr and the IE8 detect (I created it):
/*!
* IE8
* #cc_on Conditional Compilation to test the
* JavaScript versions
*/
conditionizr.add('ie8', [], function () {
var version = false;
/*#cc_on if (#_jscript_version > 5.7 && !/^(9|10)/.test(#_jscript_version))
version = true #*/
return version;
});
This gives you:
if (conditionizr.ie8) {
// stuff for ie8
}
conditionizr.on('ie8', function () {
// callbacks
});
Plus you can load polyfills/other assets. Perhaps you can load Ext.js for non-IE8 so that the app doesn't break, it just doesn't serve instead.
With Conditionizr you can ignore browsers too using !:
conditionizr.on('!ie8'[, callback]);
Just use one of IE's conditional statements within your markup:
<html>
...
<body>
<!--[if lte IE 8]>
<p>Notice: As you are using an old browser some features of this
web app may not work for you. Please update.</p>
<![endif]-->
...
</body>
</html>
Anything contained within the <!--[if lte IE 8]> block here targets any version of Internet Explorer less than or equal to IE8.
I am having problems passing javascript values between frames in chrome. In other browsers (Opera and Firefox) it works. The first frame contains the following html:
<script> variable="frame 1 value";</script>
click here
and test.html is:
<html>
<head>
<script>window.onload = function() {
div = document.getElementById("fred");
div.innerHTML="<b>" + top.frames[0].variable + "</b>";
}
</script>
</head>
<body>
<div id="fred">
hi there</div>
</body>
</html>
I have looked on this site and others, and the have seen a suggestion that because chrome pages run in different processes they cannot pass values. Is this true, and if so is there a way around it (cookies?)
Thanks,
russell
(edited) I just found another answer which says this happens only on file protocol. Like the writer of the other question, I am writing an applicaiton meant to be run off a cd, so I need to use file protocol. The version of Chrome I am using is 9.0.
ry
This has something to do with cross-site scripting which may be a security issue. Since Chrome has a very strict behavior on this, it should be impossible to achieve what you want.
Fortunately, there may be a nifty trick that you can use (if your variable is only a string):
Change the link in the first frame to test.html?foo=bar
Read window.location.href in the second frame. This will yield something like "Z:\folder\test.html?foo=bar". Now you can use string manipulation functions to extract the value of foo (in case: bar) from the href.
HTML5 Storage to the rescue! For the first frame:
<script>localStorage.setItem('variable', 'frame 1 value');</script>
click here
And for test.html:
<html><head>
<script>
window.onload = function() {
div = document.getElementById("fred");
div.innerHTML="<b>" + localStorage.getItem('variable') + "</b>";
}
</script>
</head><body>
<div id="fred">hi there</div>
</body></html>
A note of caution: IE7 and some older browsers do not support localStorage. However, you should be able to use if (typeof(localStorage) == 'undefined') {} to detect which method you need to use.
Frames are deprecated since 1997 (HTML 4.0 specification) for many reasons - so the best recommendation is do not use them.
You can also run Chrome with command line argument --disable-web-security, but it is also bad recommendation.
How can I hide a div with javascript if the browser is firefox only?
To check Firefox browser
//Javascript
var FIREFOX = /Firefox/i.test(navigator.userAgent);
if (FIREFOX) {
document.getElementById("divId").style.display="none";
}
<!-- HTML-->
<div id="divId" />
Just check a FF-specific JavaScript property. E.g.
var FF = (document.getBoxObjectFor != null || window.mozInnerScreenX != null);
if (FF) {
document.getElementById("divId").style.display = 'none';
}
This is called feature detection which is preferred above useragent detection. Even the jQuery $.browser API (of which you'd have used if ($.browser.mozilla) for) recommends to avoid useragent detection.
“Is the browser Firefox” is almost always the wrong question. Sure, you can start grovelling through the User-Agent string, but it's so often misleading that it's not worth touching except as a very very last resort.
It's also a woolly question, as there are many browsers that are not Firefox, but are based around the same code so are effectively the same. Is SeaMonkey Firefox? Is Flock Firefox? Is Fennec Firefox? Is Iceweasel Firefox? Is Firebird (or Phoenix!) Firefox? Is Minefield Firefox?
The better route is to determine exactly why you want to treat Firefox differently, and feature-sniff for that one thing. For example, if you want to circumvent a bug in Gecko, you could try to trigger that bug and detect the wrong response from script.
If that's not possible for some reason, a general way to sniff for the Gecko renderer would be to check for the existence of a Mozilla-only property. For example:
if ('MozBinding' in document.body.style) {
document.getElementById('hellononfirefoxers').style.display= 'none';
}
edit: if you need to do the test in <head>, before the body or target div are in the document, you could do something like:
<style type="text/css">
html.firefox #somediv { display: none }
</style>
<script type="text/javascript">
if ('MozBinding' in document.documentElement.style) {
document.documentElement.className= 'firefox';
}
</script>
if(document.body.style.MozTransform!=undefined) //firefox only
function detectBrowser(){
....
}
hDiv = .... //getElementById or etc..
if (detectBrowser() === "firefox"){
hDiv.style.display = "none"
}
You might try Rafeal Lima's CSS Browser Selector script. It adds a few classes to the HTML element for OS, browser, js support, etc. You can then use these classes as hooks for further CSS and/or JS. You might write a CSS (or jQuery) selector like html.gecko div.hide-firefox once the script has run.