Safari ignores window.matchMedia - javascript

I'm using window.matchMedia conditional in order to avoid the inject of a video in mobile devices. CanIUse reports that matchMedia is going to work smoothly since Safari 9 (I'm testing on it), but my code is completely ignored:
if ( window.matchMedia("(min-width: 1025px").matches) {
console.log('match');
document.addEventListener("DOMContentLoaded", function() { initialiseMediaPlayer(); }, false);
function initialiseMediaPlayer() {
(stuff here...)
}
}
This code works perfectly on Chrome, Chromium, Firefox, IE and Edge.
Does anyone had a similar issue?

The issue is in the formatting, oddly enough the other browsers fix the behavior even though it is malformed. It's missing an additional closing ")" parenthesis after the 1025px. Try:
if ( window.matchMedia('(min-width:1025px)').matches) {
console.log('match');
document.addEventListener("DOMContentLoaded", function() { initialiseMediaPlayer(); }, false);
function initialiseMediaPlayer() {
(stuff here...)
}
}

For anyone else who may come across similar issues, I found that in safari you need to include 'screen and' as well as the width setting. Other browsers seem to assume that you are talking about the screen width but safari needs it specified, at least in my case. so would be something like:
if ( window.matchMedia('screen and (min-width:1025px)').matches) {}
in this case

In my case, it was that Safari uses .addListener() instead of addEventListener() on the mediaQueryList.

If someone stumbles across this too, in my case the problem was, that safari doesn't have the .onchange property on the MediaQueryList interface.
This was just resolved in Safari 14, but the release is rather new, so use (the deprecated) .addListener if you want to ensure backwards compatibility.
Source: https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList/onchange

Related

IntersectionObserver on IE, Edge

IntersectionObserver is fairly new, experimental API, and at this moment is not fully supported by all browsers.
It will have many uses, but for now the most prominent one is lazy-loading your images, that is if you have them plenty on your website. It is recommended by Google if you audit your website with Lighthouse.
Now, there are several snippets around the web suggesting its usage but I think none of them are 100% vetted. For example I'm trying to use this one. It works like a charm on Chrome, Firefox and Opera but it doesn't work on IE and Edge.
const images = document.querySelectorAll('img[data-src]');
const config = {
rootMargin: '50px 0px',
threshold: 0.01
};
let observer;
if ('IntersectionObserver' in window) {
observer = new IntersectionObserver(onChange, config);
images.forEach(img => observer.observe(img));
} else {
console.log('%cIntersection Observers not supported', 'color: red');
images.forEach(image => loadImage(image));
}
const loadImage = image => {
image.classList.add('fade-in');
image.src = image.dataset.src;
}
function onChange(changes, observer) {
changes.forEach(change => {
if (change.intersectionRatio > 0) {
// Stop watching and load the image
loadImage(change.target);
observer.unobserve(change.target);
}
});
}
To be more precise, the code should recognize if browser supports IntersectionObserver and if NOT it should immediately load all images without utilizing the API and write to console that IntersectionObserver is not supported. So, the snippet above fails to do that.
As far as my investigation goes, when testing with IE 11 and Edge 15, they spit an error to console that they don't recognize forEach, despite the fact that they should support it.
I've tried to shim forEach, and even replace forEach with good old for, but I can't get this snippet to work on IE and Edge.
Any thoughts?
After some tests, I found the reason.
First, I let the observer observe document.body, it works. Then I guess the observer can't observe empty elements, so I set 1px border on the element I want to observe, and then it works.
This may be a bug on Edge, because Chrome and Firefox can both observe empty elements.

Stylesheet switcher in Safari 5.1 WebKit 534

I have a stylesheet switcher which works fine in all mainstream browsers until Safari 5.1 and possibly a past version of Chrome. The source of the problem appears to be in WebKit version 534. Other designers have experienced similar problems:
https://discussions.apple.com/thread/3215084?start=0&tstart=0
This version of WebKit appears not to action:
a.disabled = false
in the following script:
function changeLayout(description){
var i, a;
for(i=0; (a = document.getElementsByTagName("link")[i]); i++){
if(a.getAttribute("title") == description){a.disabled = false;}
else if(a.getAttribute("title") != "default"){a.disabled = true;}
}
}
(or perhaps it may be the case that it will only allow one active stylesheet, the default?)
I have alternative code I can deliver to switch the stylesheet but it is more onerous and I only want to run it if the usual method would fail.
Is there a way I could test if the browser is respecting
"a.disabled = false" (or true for that matter)
and then deliver the alternative code if not?
OR is there a reliable way to test for WebKit version 534?
I know jQuery.Browser can detect things like webkit and versions. Check it out here:
http://api.jquery.com/jQuery.browser/
Edit
Looks like it is now depricated, replaced with jQuery.Support:
http://api.jquery.com/jQuery.support/

Stop jQuery function from executing in IE

I'm having some code that sadly doesn't work in Internet Explorer and because it's not absolutely neccesary to have this code work in all browsers I'd like to stop it from executing in IE unless there is someway to fix it so it works in IE too (see this thread). How would this be (if it is) possible? Thanks
jQuery has functionality for seeing if a browser is any form of MSIE
if (!$.browser.msie) {
// jquery function
}
You can use Conditional comment statements to do things in IE differently.
Take a look here http://msdn.microsoft.com/en-us/library/ms537512(v=vs.85).aspx
You would want to test to see if the browser is not IE and then do the code.
Or you can use some jQuery browser detection which would allow you only to execute specific javascript code depending on the browser.
if (!$.browser.msie) {
// jquery function
}
However I would recommend trying to get your javascript code to work in all browsers (maybe not IE6 ;) )
The jQuery object exposes a "browser" property:
if (jQuery.browser !== "msie") {
// do the thing
}
Use:
if ( !jQuery.browser.msie ) {
//Your code
}

Browser Issue: Charts are not rendered on IE8

We have inhouse library which uses canvas for displaying charts in my application. And dojo as scripting language.Everything is fine, but my charts are not appearing in IE8.
I google about this, and found that there is some VML issue in IE8.
I found this:
var printChart = function(time, freq){
if (!document.namespaces['g_vml_']) {
document.namespaces.add('g_vml_', 'urn:schemas-microsoft-com:vml', '#default#VML');
}
if (!document.namespaces['g_o_']) {
document.namespaces.add('g_o_', 'urn:schemas-microsoft-com:office:office', '#default#VML');
}
if (freq === undefined) {
this.freq = "1mi";
}
if (time === undefined) {
this.time = "1dy";
}
self.reload();
}
Now I was trying to add this in my DOJO code and that is creating problem.
As when I do document.namespace I get firebug error 'document.namespaces is undefined'.
Q: How can we fix this, are the any better alternative approaches for the same, basic problem am having is browser related, charts are rendered properly on other browsers but not on IE8, any suggestions ?
Update:
What are ways to deal with such cross browser issue ?
Regarding the cross-browser issues you mentioned, there are basically two ways: browser sniffing and object detection. Browser sniffing is to detect the browser vendor and version. For example, you can know that the browser is IE 8 or Firefox 4.0 from the navigator object. Object detection is to test whether a object/function is available on the browser before actually using it.
For the problem you have here, you can use the two approaches. For example, you can sniff the browser using dojo.isIE.
if (dojo.isIE == 8) {
//Your code to add the namespace
}
Or you can use:
if (document.namespaces) {
// Your code to add the namespace
}

The best way of checking for -moz-border-radius support

I wanted some of those spiffy rounded corners for a web project that I'm currently working on.
I thought I'd try to accomplish it using javascript and not CSS in an effort to keep the requests for image files to a minimum (yes, I know that it's possible to combine all required rounded corner shapes into one image) and I also wanted to be able to change the background color pretty much on the fly.
I already utilize jQuery so I looked at the excellent rounded corners plugin and it worked like a charm in every browser I tried. Being a developer however I noticed the opportunity to make it a bit more efficient. The script already includes code for detecting if the current browser supports webkit rounded corners (safari based browsers). If so it uses raw CSS instead of creating layers of divs.
I thought that it would be awesome if the same kind of check could be performed to see if the browser supports the Gecko-specific -moz-border-radius-* properties and if so utilize them.
The check for webkit support looks like this:
var webkitAvailable = false;
try {
webkitAvailable = (document.defaultView.getComputedStyle(this[0], null)['-webkit-border-radius'] != undefined);
}
catch(err) {}
That, however, did not work for -moz-border-radius so I started checking for alternatives.
My fallback solution is of course to use browser detection but that's far from recommended practice ofcourse.
My best solution yet is as follows.
var mozborderAvailable = false;
try {
var o = jQuery('<div>').css('-moz-border-radius', '1px');
mozborderAvailable = $(o).css('-moz-border-radius-topleft') == '1px';
o = null;
} catch(err) {}
It's based on the theory that Gecko "expands" the composite -moz-border-radius to the four sub-properties
-moz-border-radius-topleft
-moz-border-radius-topright
-moz-border-radius-bottomleft
-moz-border-radius-bottomright
Is there any javascript/CSS guru out there that have a better solution?
(The feature request for this page is at http://plugins.jquery.com/node/3619)
How about this?
var mozborderAvailable = false;
try {
if (typeof(document.body.style.MozBorderRadius) !== "undefined") {
mozborderAvailable = true;
}
} catch(err) {}
I tested it in Firefox 3 (true) and false in: Safari, IE7, and Opera.
(Edit: better undefined test)
I know this is an older question, but it shows up high in searches for testing border-radius support so I thought I'd throw this nugget in here.
Rob Glazebrook has a little snippet that extends the support object of jQuery to do a nice quick check for border-radius support (also moz and web-kit).
jQuery(function() {
jQuery.support.borderRadius = false;
jQuery.each(['BorderRadius','MozBorderRadius','WebkitBorderRadius','OBorderRadius','KhtmlBorderRadius'], function() {
if(document.body.style[this] !== undefined) jQuery.support.borderRadius = true;
return (!jQuery.support.borderRadius);
}); });
Attribution
That way, if there isn't support for it you can fall back and use jQuery to implement a 2-way slider so that other browsers still have a similar visual experience.
Why not use -moz-border-radius and -webkit-border-radius in the stylesheet? It's valid CSS and throwing an otherwise unused attribute would hurt less than having javascript do the legwork of figuring out if it should apply it or not.
Then, in the javascript you'd just check if the browser is IE (or Opera?) - if it is, it'll ignore the proprietary tags, and your javascript could do it's thing.
Maybe I'm missing something here...
Apply CSS unconditionally and check element.style.MozBorderRadius in the script?
As you're already using jQuery you could use jQuery.browser utility to do some browser sniffing and then target your CSS / JavaScript accordingly.
The problem with this is that Firefox 2 does not use anti-aliasing for the borders. The script would need to detect for Firefox 3 before is uses native rounded corners as FF3 does use anti-aliasing.
I've developed the following method for detecting whether the browser supports rounded borders or not. I have yet to test it on IE (am on a Linux machine), but it works correctly in Webkit and Gecko browsers (i.e. Safari/Chrome and Firefox) as well as in Opera:
function checkBorders() {
var div = document.createElement('div');
div.setAttribute('style', '-moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px;');
for ( stylenr=0; stylenr<div.style.length; stylenr++ ) {
if ( /border.*?-radius/i.test(div.style[stylenr]) ) {
return true;
};
return false;
};
If you wanted to test for Firefox 2 or 3, you should check for the Gecko rendering engine, not the actual browser. I can't find the precise release date for Gecko 1.9 (which is the version that supports anti-aliased rounded corners), but the Mozilla wiki says it was released in the first quarter of 2007, so we'll assume May just to be sure.
if ( /Gecko\/\d*/.test(navigator.userAgent) && parseInt(navigator.userAgent.match(/Gecko\/\d*/)[0].split('/')[1]) > 20070501 )
All in all, the combined function is this:
function checkBorders() {
if ( /Gecko\/\d*/.test(navigator.userAgent) && parseInt(navigator.userAgent.match(/Gecko\/\d*/)[0].split('/')[1]) > 20070501 ) {
return true;
} else {
var div = document.createElement('div');
div.setAttribute('style', '-moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px;');
for ( stylenr=0; stylenr<div.style.length; stylenr++ ) {
if ( /border.*?-radius/i.test(div.style[stylenr]) ) {
return true;
};
return false;
};
};

Categories

Resources