Thursday, April 10, 2008

Redefining console.log() For Browsers Without Firebug

posted by Jonah Dempcy
Firebug

I use Firebug's console.log() method extensively when developing code. But, when viewing the site in Internet Explorer, Safari, Opera or other browsers that don't have Firebug, console.log() throws an error. Rather than wrap each log statement in a try/catch, I just add this bit of code during development that checks for Firebug and redefines the console.log() method if Firebug isn't installed:

 // When logging messages with console.log()
 // if user doesn't have Firebug, write them to the DOM instead
 if (typeof console == "undefined") {
 
  // Create an unordered list to display log messages
  var logsOutput = document.createElement('ul');
  document.getElementsByTagName('body')[0].appendChild(logsOutput);
  
  // Define console.log() function
  console = {
   log: function(msg) {
    logsOutput.innerHTML += '<li>' + msg + '</li>';
   }
  };
 }

Logging Statements in Production Code

If you don't want to have to remove your console.log() statements in production code, you can set a "development mode" flag that ignores log messages.
var DEVELOPMENT_MODE = true;

// When logging messages with console.log()
// if user doesn't have Firebug, write them to the DOM instead
if (typeof console == "undefined" && DEVELOPMENT_MODE == true) {
 
  // Create an unordered list to display log messages
  var logsOutput = document.createElement('ul');
  document.getElementsByTagName('body')[0].appendChild(logsOutput);
  
  // Define console.log() function
  console = {
    log: function(msg) {
      logsOutput.innerHTML += '<li>' + msg + '</li>';
    }
  };
} else if (DEVELOPMENT_MODE == false) {
  console = {
    log: function() {} // Do nothing
  };
}
I made the flag uppercase since it follows naming conventions for constants. Now you can set the DEVELOPMENT_MODE flag when deploying to production environments and leave your logging messages intact, if you desire.

Take note that this adds unnecessary page-weight from the logging messages, so to fully optimize the code, logging should be removed. But, leaving some amount of logging in the production code is probably acceptable, as long as it doesn't add more than a few kilobytes to the page weight. As long as you're using GZip, minifying your JavaScript and serving it with far future expires headers, a few extra k aren't going to hurt anything.

Redefining All Firebug Methods

If you use other Firebug methods, such as assert(), trace() or error(), then you may want to use the following code, provided by the developers of Firebug as part of the Firebug Lite project.

This code redefines all Firebug methods as empty functions when Firebug isn't installed on the browser:
if (!window.console || !console.firebug) {
  var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml",
  "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];

  window.console = {};
  for (var i = 0; i < names.length; ++i)
    window.console[names[i]] = function() {}
}

Labels: , ,

2 Comments:

Blogger Jonah Dempcy said...

I found a more full-fledged solution for those in need of more functionality: http://icant.co.uk/sandbox/fauxconsole/

April 23, 2008 at 5:10 PM  
Blogger Unknown said...

Note that the suggestion to overwrite the console.log() method might result in an error: "setting a property that has only a getter".

The
window.console["log"] = function() {}

alternative prevents this error.

July 31, 2008 at 2:39 AM  

Post a Comment

Subscribe to Post Comments [Atom]

<< Home