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
}
Related
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>-->
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'){
...
}
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/
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
}
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;
};
};