views:

522

answers:

2

I have a javascript widget (a piece of embedded JS and HTML code) that's embedded on other sites. What should I do to make sure it's variable names don't clash with the hosting page variables?

I'd like this widget to be "inlined" meaning on the same page as the hosting page, not in an iframe, what's the best way to avoid name clashes with the hosting page or clashes with other widgets?

Name clashes can happen in several ways:

  • Javascript variable names
  • Javascript function names
  • DOM elements identifiers
  • CSS class names
  • maybe more...

I can think of several ways to avoid name clashes, but I was wondering if there's a best-practice or other general recommendations. So here's my 2c:

  1. Just use long and try-to-be-unique names. That's ugly and not full-proof, but is simple in concept.
  2. Use an iframe. But as mentioned, I don't want to use an iframe for several reasons. I want the widget to inherit style attributes from the page (such as default font and background color) and most importantly, I don't know how large the widget is going to be. It depends on real-time data and may be of any size.
  3. Use anonymous functions for better scoping, e.g. (function(){my code here})(). This solution, while elegant, still does not work for me b/c first, it only solves the JS name clashed but not the DOM ID ones or CSS class names and second, I also use jsonp for which I need to provide a callback function name, which eventually needs to be in the global scope, so it cannot be nested in the anonymous function scope.
  4. Create a namespace mechanism in javascript that'll provide uniqueness of JS variables and function. Something of the style window['my_app'][variable_name] or window['my_app']function_name. That's a bit ugly as well, but at least I have control over the namespace and can generate guarantied to be unique namespaces.

Thanks!

+4  A: 

Javascript namespaces:

http://www.codeproject.com/KB/scripting/jsnamespaces.aspx

It is heavily used in several javascript frameworks/libraries, such as YUI: http://developer.yahoo.com/yui/yahoo/

Ward Werbrouck
+3  A: 

In my previous project I had a widget that was embedded on other sites, and to prevent name conflicts I prefixed all names that would be used in the embedding sites with a two letter prefix (I got the idea from Objective C, where all classes start with a prefix like NS...).

Of course I also used namespaces (e.g. var Foo = { bar: function() { ... }}) and "classes" (using John Resig's class implementation), because I use them regardless if I have a widget or not, but the names of the namespaces, classes and global variables or functions were prefixed - e.g. HMWidget, HMClass, hmDoSomething(), etc.

Regarding DOM IDs and CSS classes - first, I had to get rid of most IDs because of the possibility of having multiple widgets from my service on the same site. So the only IDs that were left were something like "widget_12345" to tell the widgets apart. The rest of the elements were identified by CSS classes, and all CSS declarations were done in relation to the main widget container (e.g. ".my_widget .left_column" instead of just ".left_column").

Psionides