Stop jQuery function from executing in IE - javascript

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
}

Related

Safari ignores window.matchMedia

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

Enable/Disable debug code dynamically

I'm writing a decent sized JavaScript animation library, that I would like to include debugging code in. I could easily do a check :
if(myLib.debugger){
console.warn('warning message');
}
However if this runs a couple thousand times a second, it would eventually cause performance issues. Add in a few more checks throughout the code and the effect will be even more noticeable.
What I'm wondering is if it would be possible to check onload if the debugger should be enabled, and if so... turn something like this:
//debugger if(!this.name) console.warn('No name provided');
into:
if(!this.name) console.warn('No name provided');
Leaving the code commented if its not enabled, and uncommenting it if it is, thus removing any possible performance issues. Could this be done somehow with a regular expression on the entire script if loaded in through ajax? I'm trying to avoid the need for 2 versions of the same code, lib.dbug.js and a lib.js.
Cross browser compatibility is not of great importance for this (I'm really only worried about new browsers), I see it as nice to have item. If its possible however, it would be a great thing to have.
Any insight would be greatly appreciated.
The simplest way to do this would be to check if the debugger should be disabled and if so, replace it with a mock object that does nothing at the very start of your script:
if (!myLib.debugger) {
window.console = (function () {
var newConsole = {};
var key;
for (key in window.console) {
if (typeof window.console[key] === 'function') {
newConsole[key] = function () {};
}
}
return newConsole;
}());
}
The overhead of this approach should be negligible.
If this is a JavaScript library... then I'd expect as a 3rd party developer that I could download/use 2 versions. The production version (no debug, AND minimized). If I wanted to debug, I would point to the debug version of the library instead.
e.g.
<script src="foo-lib-min.js"></script>
<!-- swap to this for debugging <script src="foo-lib-full.js"></script>-->

How to only wait for document.readyState in IE and fire instantly for all other browsers?

I have written a CSS and Javascript lazyloader to dynamically load resources for seperate pagelets (in the way that Facebook renders a page with it's BigPipe technology).
In short an HTML frame is rendered first, then separate parts of the page are all generated asynchronously by the server. When each pagelet arrives the pagelets css is loaded first, then its innerHTML is set, then finally we load any required javascript for this pagelet and initialise it.
Everything works perfectly and perceived load time is pretty much instantaneous for any given page.
However in IE, I occasional I get Method does not support method or property when initialising the scripts.
I have solved this by checking for document.readyState before loading the scripts.
Now this isn't a huge issue but it adds on average 170ms to a pageload in chrome or firefox. Which is not needed.
function loadScripts(init){
// ensure document readystate is complete before loading scripts
if( doc.readyState !== 'complete'){
setTimeout(function(){
loadScripts(init);
}, 1 );
}
else{
complete++;
if(complete == instance.length){
var scripts = checkJS(javascript);
if(scripts.length) {
LazyLoad.js(scripts, function(){
runPageletScript();
for (var i = 0; i < scripts.length; ++i) {
TC.loadedJS.push(scripts[i]);
}
});
}
else{
runPageletScript();
}
}
}
}
What I am looking for is a modification to this script which will only implement the 'wait' in IE, if it is any other browser it will just fire straight away. I cannot use a jQuery utility like $.Browser and need it to be the tiniest possible method. I hate to use any form of browser detection but it appears as though its my only solution. That said if anyone can come up with another way, that would be fantastic.
Any suggestions would be gratefully received.
You could use JScript conditional compilation, which is only available in IE browsers (up to IE10).
Because it's a comment, it's best to place it inside new Function as minifiers might remove it, changing your code. Though in general you should avoid using new Function, in this case there's not really any other way to prevent minifiers from removing it.
Example:
var isIE = !(new Function('return 1//#cc_on &0')());
However, it seems that your main issue is that the DOM hasn't loaded yet -- make sure that it has loaded before running any loader using the DOMContentLoaded event (IE9+):
document.addEventListener('DOMContentLoaded', function () {
// perform logic here
});
Here is just another solution as the solution from Qantas might not always work. For instance on UMTS connections it could happen that providers remove comments to save bandwith (maybe they preserve conditional comments):
if(navigator.appName == 'Microsoft Internet Explorer'
&& doc.readyState !== 'complete'){
...
}

Why would Dojo 1.6 fail to properly load javascript file in IE8 using dojo.require?

The following code worked with Dojo 1.5 in Firefox and Internet Explorer 8.
With Dojo 1.6, it still works in Firefox, but does not work in IE8.
I get an Object doesn't support this property or method error when wrappingFunctionInPlainJsFile() is called.
HTML page:
<div dojoType="widget.MyCustomWidget"></div>
In widget/MyCustomWidget.js
dojo.provide("widget.MyCustomWidget");
dojo.require("js.plainJsFile");
dojo.declare("widget.MyCustomWidget", [dijit._Widget, dijit._Templated], {
...
// this gets called when the widget is clicked on in the UI
run: function() {
wrappingFunctionInPlainJsFile();
},
...
});
In js/plainJsFile.js
dojo.provide("js.plainJsFile");
function someFunction() {
}
function wrappingFunctionInPlainJsFile(){
new someFunction();
}
Any ideas on what I am doing wrong would be greatly appreciated.
Note: If I import the plainJsFile.js directly on the HTML page instead of using dojo.require then I have no problems.
I believe that the purpose of the dojo.require system to break your code up into modules where those modules aren't just arbitrary chunks of js, but dojo.declare'd objects. When you write dojo.provide("js.plainJsFile"), by convention I'd expect there to be an global object called "js" which had a property "plainJsFile". See the code example on this page.
I actually use dojo.require the way that you do, ignoring the convention I'm describing, and it works just fine -- in firefox. IE won't swallow it though. IE will behave if all the required js files are compressed into a single file (which you mentioned solves your problem).
So, basically, I think that IE is less flexible about scope while dojo.require is doing its thing, and you putting function declarations in a "module" like that is breaking things. Try going with the convention and see if that helps.
I tried the dojo mailing list and got a fix courtesy of Karl Tiedt.
See here: http://dojo-toolkit.33424.n3.nabble.com/Why-would-Dojo-1-6-fail-to-properly-load-javascript-file-in-IE8-using-dojo-require-td3204800.html#a3204894
Copy/paste of solution.
"Its an IE quirk....
dojo.provide("js.plainJsFile");
(function() {
function someFunction()
wrappingFunctionInPlainJsFile = function() {
new someFunction();
}
})();
should work... I always use my name spaces though and do it this way
dojo.provide("js.plainJsFile");
(function(pjsf) {
pjsf.someFunction = function()
pjsf.wrappingFunctionInPlainJsFile = function(){
new someFunction();
}
})(js.plainJsFile);
"
Note: I tried the above solution and it worked for me in IE8 and Firefox.

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
}

Categories

Resources