i'm trying to make a little script to style "select" tags in my html testing for the support of the "appearance" style property:
if ("webkitAppearance" in select.style ||
"MozAppearance" in select.style ||
"oAppearance" in select.style ||
"appearance" in select.style ||
"-ms-expand" in select.style) {
return;
}
// else apply wrapper and style it.
The problem is that i don't know how to check for -ms-expand property, because it's not working and i don't want to user browser version sniffing in this case.
You can't check -ms-expand in javascript, because it is pseudo-element, and it do not affect to content. You can't detect it like ::before/::after in Modernizr, but -ms-expand is enabled in IE 10+, so better will be to detect is IE 10 or higher by javascript:
Detection IE 11:
!window.ActiveXObject && "ActiveXObject" in window
Detection IE 10:
var isIE10 = false;
/*#cc_on
if (/^10/.test(#_jscript_version)) {
isIE10 = true;
}
#*/
Not the most optimal solution in terms of performance, but you could try this:
var expandSupport = (function(){
try{
var style = document.createElement("style");
style.textContent = "#ie10-test::-ms-expand{ }";
document.body.appendChild(style);
var supported = !!style.sheet.rules.length;
document.body.removeChild(style);
return supported;
} catch(e){ return false; }
}());
document.body.appendChild(document.createTextNode(expandSupport ? "Your browser appears to support the -ms-expand pseudo-element" : "Your browser doesn't appear to support the -ms-expand pseudo-element"));
Fiddle here.
The reason this works is because browsers will discard any selectors they don't support or can't interpret, which means any browser that doesn't understand what the "::-ms-expand" pseudo-element is probably isn't IE10 or up.
Essentially, all that this code is doing is creating a dummy <style> tag, adding a ruleset that only IE10+ is expected to support, and reporting back the number of rules found in it.
Related
I wrote some Javascript code that works perfectly in all major browsers. Of course I made sure that none of this would be executed by Internet Explorer by creating a function that figures out what browser the user is using.
Here's the problem however: Even if I told IE not to execute the code, the browser still reads all of my Javascript and since it finds something it doesn't recognise it stops running any other Javascript.
The only thing I could think of doing was creating a function that would return if the user is using IE, but that doesn't seem to work since I think the problem comes from IE initially parsing my script and not being able to understand modern JS syntax.
Here's a simplified version of my code:
class Section {
constructor(dom, startPosition, endPosition, backgroundPosition) {
this.dom = dom;
this.startPosition = startPosition;
this.endPosition = endPosition;
this.backgroundPosition = backgroundPosition;
}
}
function isIE() {
ua = navigator.userAgent;
/* MSIE used to detect old browsers and Trident used to newer ones*/
var is_ie = ua.indexOf("MSIE ") > -1 || ua.indexOf("Trident/") > -1;
return is_ie;
}
let sections = [];
function sectionParallax() {
if (!isIE()) {
sections.push( new Section("test", 123, 123, 123))
}
}
IE's console reports:
SCRIPT1002: Syntax error
On class Section.
I'm completely out of ideas on what to do here. How do I make sure IE doesn't load this part of the code?
JavaScript classes and constructor not support IE browser, so, in the IE browser, it will show the "SCRIPT1002: Syntax error" error.
You could modify your code as below:
var Section = /** #class */ (function () {
function Section(dom, startPosition, endPosition, backgroundPosition) {
this.dom = dom;
this.startPosition = startPosition;
this.endPosition = endPosition;
this.backgroundPosition = backgroundPosition;
}
return Section;
}());
function isIE() {
ua = navigator.userAgent;
/* MSIE used to detect old browsers and Trident used to newer ones*/
var is_ie = ua.indexOf("MSIE ") > -1 || ua.indexOf("Trident/") > -1;
return is_ie;
}
var sections = [];
function sectionParallax() {
if (!isIE()) {
/*If not using IE browser. */
var newsection = new Section("test", 123, 123, 123);
sections.push(newsection);
}
}
The JS parser has to parse the JavaScript you tell it to load, even if it is a function that never executes.
If you want to stop IE from loading it, then don't load the <script> which contains it. This means you need to dynamically add the <script> if the browser does support the feature.
If you need to support IE, then don't deliver JS to the browser that uses syntax IE doesn't recognise. Consider using a tool like Babel to transpile it to an older version of JavaScript which IE does support.
You could check for IE before loading the script with a Conditional Comment :
<!--[if !IE]>-->
<script src="script.js"></script>
<!--<![endif]-->
I'm looking for a solution how we can detect the support of css flex-box and flex-wrap by JavaScript.
I'm aware of modernizr which can do the job but my client does not allow us to load any scripts inside the head section, unfortunately this does not work when loading in the footer.
What is a proper way to achieve this detection on all kind of browsers / devices?
how we can detect the support of css flex-box and flex-wrap by
JavaScript.
Create an element and check the style property. If it is supported, it will return nothing i.e. '' else it will return undefined.
For example, if you run the below snippet in Chrome you will get undefined for columns and '' for flex-wrap.
Snippet:
console.log('flex = ' + document.createElement("p").style.flex);
console.log('columns = ' + document.createElement("p").style.columns);
console.log('flex-wrap = ' + document.createElement("p").style.flexWrap);
Although you have mentioned only Javascript in your question, but there is a CSS way of feature detection as well.
The #supports rule, also called CSS Feature Queries.
You provide the CSS declaration as the condition and the browser will execute that to return whether it supports or not. For example, the following CSS will apply green background color if flex is supported.
#supports (display: flex) {
div { background-color: #0f0; }
}
The browser support is good amongst all modern browsers, barring IE (as usual). For IE and (Safari < 9), you will need to keep a fallback option when #supports rule fails.
Combining the above two, there is an API around that as well which you can use in Javascript to do feature detection.
var isColumnSupported = CSS.supports('columns', '');
console.log('columns supported: ' + isColumnSupported);
var isFlexWrapSupported = CSS.supports('flex-wrap', 'wrap');
console.log('flex-wrap supported: ' + isFlexWrapSupported);
Since CSS.supports() is not supported on IE
This robust method can test any property:value support:
var cssPropertySupported = (function(){
var mem = {}; // save test results for efficient future calls with same parameters
return function cssPropertySupported(prop, values) {
if( mem[prop+values] )
return mem[prop+values];
var element = document.createElement('p'),
index = values.length,
name,
result = false;
try {
while (index--) {
name = values[index];
element.style.display = name;
if (element.style.display === name){
result = true;
break;
}
}
}
catch (pError) {}
mem[prop+values] = result;
return result;
}
})();
///////// TEST: ////////////////////
console.log(
cssPropertySupported('display', ['-ms-flexbox', '-webkit-box', 'flex'])
)
You manually need to provide the test function all the possible property names since the code cannot guess (too many possibilities). This keeps the test code slim instead of it have all possible property names already within it.
I have been searching on the internet for a reason why my fullscreen javascript doesn't work in Safari, but yet works in webkit browser Chrome. It seems to that safari doesn't support the element.ALLOW_KEYBOARD_INPUT add-on for webkitRequestFullScreen.
function cancelFullScreen(el) {
var requestMethod = el.cancelFullScreen || el.webkitCancelFullScreen || el.mozCancelFullScreen || el.exitFullscreen;
if (requestMethod) { // cancel full screen.
requestMethod.call(el);
} else if (typeof window.ActiveXObject !== "undefined") { // Older IE.
var wscript = new ActiveXObject("WScript.Shell");
if (wscript !== null) {
wscript.SendKeys("{F11}");
}
}
}
function requestFullScreen(el) {
// Supports most browsers and their versions.
var requestMethod = el.requestFullScreen || el.webkitRequestFullScreen(el.ALLOW_KEYBOARD_INPUT) || el.mozRequestFullScreen || el.msRequestFullScreen;
if (requestMethod) { // Native full screen.
requestMethod.call(el);
} else if (typeof window.ActiveXObject !== "undefined") { // Older IE.
var wscript = new ActiveXObject("WScript.Shell");
if (wscript !== null) {
wscript.SendKeys("{F11}");
}
}
return false
}
function toggleFull() {
var elem = document.body; // Make the body go full screen.
var isInFullScreen = (document.fullScreenElement && document.fullScreenElement !== null) || (document.mozFullScreen || document.webkitIsFullScreen);
if (isInFullScreen) {
cancelFullScreen(document);
} else {
requestFullScreen(elem);
}
return false;
}
Does anybody know a way to make safari accept fullscreen yet still be able to handle keyboard inputs?
According to Apple's documentation, this is supposed to work in Safari 5.1 and later, but obviously it doesn't. I filed a bug report with Apple (which they don't make public), and the reply was as follows:
Engineering has determined that this issue behaves as intended based on the following:
We intentionally disable keyboard access in full screen for security reasons.
I have replied asking that they at least update the documentation and make the lack of feature support detectable somehow. I will update here if I get a reply.
Unfortunately, there isn't a good way to even do feature detection, since element.ALLOW_KEYBOARD_INPUT is defined in Safari, and the function call with that flag doesn't throw an error. The only remaining option is to parse the user agent string (try this library).
Obviously, Apple doesn't yet document which version supports this, but according to this, it stopped working as of v5.1.2. That would leave a very small number of people using 5.1 un-patched, if it ever even worked at all. So it's probably not even worth detecting the version.
As a fallback, I would expand the desired DOM element to fill the browser window by setting CSS height and width to 100% and position to "fixed" or "absolute".
Update: It looks like the documentation has been corrected and no longer mentions the ALLOW_KEYBOARD_INPUT flag.
This has been fixed in Safari 10.1!
Under the "Safari Browser Behavior" section.
I am trying to change class name of two elements during onload.
Here is my code for the same :
var browserName=navigator.appName;
var tfElem = document.getElementById("TTlExpct");
var blTfElem = document.getElementById("BTLExpct");
if (browserName=="Microsoft Internet Explorer")
{
tfElem.className ="pn-tf";
blTfElem.className ="pn-tf active";
}
else
{
tfElem.setAttribute('class', 'pn-tf');
blTfElem.setAttribute('class', 'pn-tf active');
}
The else block takes care of the code if its not IE, in mozilla, this is working fine, class name is getting set.
Its not working in IE7 and IE8
and
in chrome, it works only if i reload the page again.
Any help will be appreciated .
There is a bug in the implementation of setAttribute in old versions of IE. In newer versions of IE that bug may be emulated if you do not use a Doctype that triggers standards mode.
Replace:
foo.setAttribute('class', value);
With:
foo.className = value;
Do this everywhere. Don't try to do browser detection. All browsers that support setAttribute('class', value) also support foo.className = value.
The code in your question should be rewritten as:
var tfElem = document.getElementById("TTlExpct");
var blTfElem = document.getElementById("BTLExpct");
tfElem.className ="pn-tf";
blTfElem.className ="pn-tf active";
Reading this article I've found a following piece of code:
if ('v'=='\v') { // Note: IE listens on document
document.attachEvent('onstorage', onStorage, false);
}
Is this method 'v'=='\v' a great idea? Is this the shortest way to detect IE ever?
You can check for Trident, IE's engine, by the following:
var trident = !!window.ActiveXObject;
As stated on MSDN it is only supported in IE.
Edit:
Note: above code returns false in IE-11, If you want to detect also IE-11 use this:
var isIE = "ActiveXObject" in window; //window.ActiveXObject !== undefined;
If you can avoid it, don't test for browsers. Do feature detection. This will mean that your code is (more likely to be) future-proof. In this case, for instance, if you discovered that the browser was IE and decided to use attachEvent because of it, you would miss out on the fact that addEventListener (superior) is available in IE9.
In this case, test to see if document.addEventListener exists. If it does, you have the answer.
if (document.addEventListener) {
document.addEventListener(...);
} else {
document.attachEvent(...);
}
Edit: duri's comment above shows that this test fails in IE9 (as per standards), which actually means it is a perfect test for addEventListener, since that is available from IE9. However it is still far, far better to program for specific functionality, rather than specific browsers.
To check if the browser is Internet Explorer, use feature detection to check for documentMode:
http://msdn.microsoft.com/en-us/library/ie/cc196988%28v=vs.85%29.aspx
This code checks to see if the browser is Internet Explorer 8, 9, 10, or 11:
var docMode = document.documentMode,
hasDocumentMode = (docMode !== undefined),
isIE8 = (docMode === 8),
isIE9 = (docMode === 9),
isIE10 = (docMode === 10),
isIE11 = (docMode === 11),
isMsEdge = window.navigator.userAgent.indexOf("Edge/") > -1;
// browser is IE
if(hasDocumentMode) {
if(isIE11){
// browser is IE11
} else if(isIE10){
// browser is IE10
} else if(isIE9){
// browser is IE9
} else if(isIE8){
// browser is IE8
}
} else {
// document.documentMode is deprecated in MS Edge
if(isMsEdge){
// browser is MS Edge
}
}
Checking document.documentMode will only work in IE8 through IE11, since documentMode was added in IE8 and has been deprecated / removed in MS Edge.
http://msdn.microsoft.com/en-us/library/ff406036%28v=vs.85%29.aspx
I hope this helps!
UPDATE
If you really need to detect IE7, check for document.attachEvent:
var isIE7 = (document.attachEvent !== undefined);
if(isIE7) {
// browser is IE7
}
IE7 returns a object, but if the browser is IE11 (for example), then this would come back as undefined, since IE11 does not have attachEvent.
UPDATE:
Added check for MS Edge. document.documentMode was deprecated in MS Edge. Due to the nature of MS Edge, you can check for Edge/ in the User Agent. Microsoft is making it difficult to use feature detection in MS Edge.
The JavaScript includes() method is not supported in IE11 and earlier. So you can use code to check whether if the includes() method is supported. This can work for all versions of IE. But the includes method isn't for early versions of Chrome, Firefox, Safari, and Opera. This may not be the most efficient way to detect IE.
var aString = "something";
if(!aString.includes){
alert("You are using IE");
} else {
alert("You are not using IE");
}