Indestructible JavaScript Widgets
Notes from @premasagar's session at BarCampBrighton4, the Music Library, Brighton, UK - 5/6th September, 2009
iFrame widgets
- E.g. <iframe src="http://digg.com/tools/diggthis.php?u=http://dharmafly.com"></iframe>
- Easy to develop
- Widget CSS and JavaScript are protected from containing document
- Can use standards mode widget in quirks mode document
- Can't read or write to the main DOM
- Can't display content outside of widget area (e.g. no lightboxes)
- Can't communicate with containing document or other widgets
- This is changing in HTML5:
- postMessage API in latest browsers, which anyway requires JavaScript in the containing document
- sandbox and seamless attributes
- Slightly longer to load
- Good for simple, self-contained widgets
JavaScript widgets
- E.g.
<script src="http://www.bbc.co.uk/worldservice/widget/widget.js" type="text/javascript"></script>
<script type="text/javascript">bbcwswidget.settings({"package" : "en"});</script> - E.g. dharmafly.com/bbc-world-service-widget
- Can read and write to the main DOM, and so can affect anything on the page (e.g. lightboxes)
- Widget CSS (and JavaScript) can be affected by, and can affect the rest of the document
- If container is in quirks mode, then widget is in quirks mode
- Security! Don't let the widget server get hacked.
- Good for more complicated applications
CSS Wars
- Reset stylesheets
- No matter how careful you have been, without a reset stylesheet, CSS from the containing document will leak into the widget, in unpredictable ways, on somebody's website. E.g. background images appearing on every li in the widget.
- Normal reset stylesheets:
- Bring a baseline for all elements, cross-browser. But they do not deal with resetting styles that the containing document have declared.
- Widget reset stylesheet:
- For a widget, all HTML elements used in the widget should have default values set for every CSS property.
- CSS specificity:
- * / div / .vcard / #bob / !important
- w3.org/TR/css3-selectors/#specificity (CSS3)
- w3.org/TR/CSS2/cascade.html#specificity (CSS2)
- No matter how specific your selector, it will be overruled somewhere in the wild. Best to use !important
- Using #ids in the stylesheet will prevent the use of multiple widgets on the page, so best to use .classes
- Some styles need to be inherited - e.g. a span element should inherit the bold font-weight of the containing strong element: <strong><span>hello</span></strong>
- Widget reset stylesheet: dharmafly.com/sqwidget/reset.css
- For widgets in either HTML4.01 or HTML5
Sqwidget (jQuery plugin)
- jQuery plugin to solve some of the core issues when developing a JavaScript widget
- Can be extended with methods specific to a particular use
- Detects and uses jQuery already in the document; otherwise loads jQuery dynamically before proceeding
- Detects the position of the <script> element used to call it, and injects the widget at that position in the DOM
- Allows multiple instances, by avoiding duplicate use of id attribute
- Simple HTML/JSON/JavaScript templating, modified from John Resig's "micro-templating" script: ejohn.org/blog/javascript-micro-templating
- Allows CSS coding without !important, and adds it dynamically
- Allows use of jQuery $(element).css({prop:val}), dynamically converting it to use !important
- To be released soon