59

I'm developing a complex website that heavily leverages jQuery and a number of scripts. On load of the site, none of my scripting is working (though I can confirm that other scripts are functioning fine). I wouldn't be posting such a lame question here on SE except for one thing:

The instant I hit F12 to turn on developer tools so I can debug my issue, everything instantly works perfectly!

Worse, if I shut down the browser, start it up, turn on Dev Tools first and visit the site, everything works as expected.

So I can't even debug the darned problem because Dev Tools fixes it! What could Dev Tools be doing that makes things work? Does it change the UA (I do some jQuery.browser detection)? Does it do something to doctype?

EDIT

All my console logging is wrapped in the following wrapper utility function:

   function log(msg){
    if (console){
        console.log(msg);
    }
   }

Any thoughts or suggestions I could try would be welcome. I'll post here if I find a solution.

OrangeDog
  • 36,653
  • 12
  • 122
  • 207
Tom Auger
  • 19,421
  • 22
  • 81
  • 104

8 Answers8

34

I appreciate I'm pretty late to the party here, but I've got a solution for IE9 that's a little different.

(function() {
    var temp_log = [];
    function log() {
        if (console && console.log) {
            for (var i = 0; i < temp_log.length; i++) {
                console.log.call(window, temp_log[i]);
            }
            console.log.call(window, arguments);
        } else {
            temp_log.push(arguments);
        }
    }
})();

Basically instead of console.log you use log. If console.log exists then it works as normal, otherwise it stores log entries in an array and outputs them on the next log where the console is available.

It would be nice if it pushed the data as soon as the console is available, but this is less expensive than setting up a custom setInterval listener.

Updated function (1 October 2012)

I've updated this script for my own use and thought I'd share it. It has a few worthy improvements:

  • use console.log() like normal, i.e. no longer need to use non-standard log()
  • supports multiple arguments, e.g. console.log('foo', 'bar')
  • you can also use console.error, console.warn and console.info (though outputs them as console.log)
  • script checks for native console every 1000ms and outputs the buffer when found

I think with these improvements, this has become a pretty solid shim for IE9. Check out the GitHub repo here.

if (!window.console) (function() {

    var __console, Console;

    Console = function() {
        var check = setInterval(function() {
            var f;
            if (window.console && console.log && !console.__buffer) {
                clearInterval(check);
                f = (Function.prototype.bind) ? Function.prototype.bind.call(console.log, console) : console.log;
                for (var i = 0; i < __console.__buffer.length; i++) f.apply(console, __console.__buffer[i]);
            }
        }, 1000); 

        function log() {
            this.__buffer.push(arguments);
        }

        this.log = log;
        this.error = log;
        this.warn = log;
        this.info = log;
        this.__buffer = [];
    };

    __console = window.console = new Console();
})();
Liam Newmarch
  • 3,935
  • 3
  • 32
  • 46
13

You have console calls, in IE these will fail if the dev tools are not open. A simple fix is to wrap any console calls in a function like:

function log(msg) {
  if(console)
    console.log(msg);
}
crappie coder
  • 351
  • 3
  • 8
  • I thought I had done just such a wrapper. But I will double check. Good suggestion. – Tom Auger Nov 11 '11 at 14:47
  • Actually, you were right on the money that it was a console.log issue. However, your wrapper isn't a sufficient check in IE9 (though it has always worked in IE7 and 8). See my answer. – Tom Auger Nov 11 '11 at 15:02
  • 1
    this worked for me but I had to use `window.console` as just `console` did not work. – Rick Glos Sep 25 '12 at 15:58
  • This solution did NOT work in my case (IE9). I just deleted all calls to console. – krm Sep 10 '14 at 00:28
2

Most of the other solutions should work great, but here's a short one liner if you don't care about catching log messages if the console is not available.

// Stub hack to prevent errors in IE
console = window.console || { log: function() {} };

This lets you still use the native console.log function directly still instead of wrapping it with anything or having a conditional each time.

Jasmine Hegman
  • 547
  • 7
  • 22
2

I have hacked it the following way

<script type="text/javascript">
    (function () {
        if (typeof console == "undefined") {
            console = {
                log : function () {}
            }
        }
    })();
</script>

And this is the first script element in the .

benqus
  • 1,119
  • 2
  • 10
  • 24
1

I find it much more convenient to simply use console && console.log('foo', 'bar', 'baz') rather than use a wrapper function.

The code you provided:

function logError(msg){
  if (console) {
    console.log(msg);
  } else {
    throw new Error(msg);
  }
}

Will produce an error for IE when dev tools are closed because console will be undefined.

zzzzBov
  • 174,988
  • 54
  • 320
  • 367
1

The console.log wrapper that I used was not sufficient to detect the console in IE9. Here's the wrapper that works from a related question on SE:

function logError(msg){
    try {
        console.log(msg);
    } catch (error) {
        throw new Error(msg);
    }
}

function log(msg){
    try {
        console.log(msg);
    } catch (error) { }
}

A proper test for the availability of the console object would be: if (typeof console === "undefined" || typeof console.log === "undefined")

Community
  • 1
  • 1
Tom Auger
  • 19,421
  • 22
  • 81
  • 104
  • Annoyingly (feature detection should win out every time), this is the only solution that worked for me with a downgraded IE9 in forced-non compatibility mode. – AndyC Jun 20 '14 at 11:01
0

I have run into this issue many times. Basically with variables we do this to check if they are valid

var somevar;
if (somevar)
 //do code

this works because somevar will resolve to undefined. But if your checking a window property for example. window.console.

if (console) <---- this throws an exception

You cannot do the same check. The browser treats it differently. Basically only doing this

if (window.console) <---- will NOT throw an exception if undefined
//some code

this will work the same as the first example. So you need to change your code to

function log(msg){
 if (window.console){
     console.log(msg);
 }
}
John
  • 126
  • 1
  • 6
0

If you have multiple parallel script files, maybe the files are being loaded/executed in a different order with developer tools on/off.

Zhonk
  • 614
  • 4
  • 13