Exploring XUL in Mozilla: The Bulletinboard Tag
Pages: 1, 2
Bulletinboard syntax
The syntax for the <bulletinboard> tag is quite simple. All you need to do is wrap any existing tags you want to be positionable with the
<bulletinboard> tag. This is a common code pattern in XUL. For instance you see the same thing with the <stack> and <deck> tags (and many others). Here's another example:
<bulletinboard>
<box id="item1">
<iframe src=http://www.news.com />
</box>
<box id="item2">
<button id="button1" class="mybutton" value="clickme" oncommand="" />
</box>
</bulletinboard>
You can now position the element with the ID item1 or item2 anywhere you want to on the screen, either placing the "top" and "left" attributes in the tags themselves or setting them via stylesheets (top: and left:).
Using bulletinboard
Our XUL bulletinboard has a few advantages to its corkboard counterpart (apart from never running out of thumbtacks). We can use JavaScript to dynamically change the position of any element in this board -- which is really why most people would be interested in using this. Again, we can revisit many DHTML sites and can practically lift the code right out of them with minor modifications to animate XUL-based elements.
Here's a simple example. Imagine if you wanted to move item2 in the listing above from its current location (which by default is 0,0) to say 200,300 (I'm assuming pixels here). In JavaScript you might write something like:
function moveIt(theNodeID, theTop, theLeft){
theNode=document.getElementById(theNodeID)
theNode.setAttribute("top",theTop) // change the y position
theNode.setAttribute("left",theLeft) // change the x position
}
And you would execute this code like this:
moveIt("item2",30,40)
There are a number of things that you need to take into consideration when developing XUL apps with <bulletinboard>:
- Elements with "views" may have speed and rendering issues. Some of these elements include <iframe>,<browser>, and form input fields. For example, you might have two <iframe> tags as separate elements -- with the current Mozilla codebase both iframes would try to paint to the same area on the screen if they overlapped.
- Always specify the bulletinboard's viewable area in advance -- meaning, always set a height and width on the bulletinboard tag. If you don't, it will minimize to the size it takes to contain each element, and if you were using this to move elements around via JavaScript, the whole page would reflow each time you moved an element beyond the current height and width of the bulletin board. (Although this might be the effect you are looking for).
- Animations will run faster if you specify the children tags using attributes instead of stylesheets. (Meaning:
<box top="30px" left="20px" />instead of<box style="top:30px;left:20px" >), because you save time not having to have a stylesheet resolution cycle in the reflow. - The order of the child tags in the bulletinboard determines their z-index. If you want to rearrange elements' stacking order you could do DOM manipulations like
removeChild()andappendChild()on the parent<bulletinboard>tag. - Bulletinboard tags can be nested. You could have animations within animations using this technique. Each bulletinboard has its own independent X,Y coordinate system.
Advanced example
For users who want to roll up their shirtsleeves a little further, I've included an advanced example of using <bulletinboard> in conjunction with JavaScript, XBL, and stylesheets. This example is a simple puzzle that allows you to drag images around and arrange them into the Mozilla.org logo image. You can find this example here. Load the puzzle.xul file and drag the images around.
Here is a screenshot of Puzzle in action:
![]() |
Puzzle in action. |
How it works:
- I created a simple XUL file with a single
<bulletinboard>with several images that I had already cut up in Fireworks. - I created a CSS file which contains the rules for the border on the bulletinboard so you could see it (it's normally invisible itself). I also added a CSS class called
draggablewhich I applied to all of the images. I added a to the-moz-bindingdraggableclass. - I created an XML file that contains the XBL binding for my draggable elements. All this does is add the JavaScript code needed for each element to know when it has received a mousedown, mousemove, or mouseup event. The JavaScript in the binding changes the target image's top and left attributes after a mousedown has already occurred and a mousemove event is happening. XBL is an excellent way for you to take potentially repetitious JavaScript code and encapsulate it into one location that you can use over and over again. I could have just as easily placed "mouseover, mousedown, and mouseout" event handlers in each of the
<image>tags, and put the JavaScript routines in another file. - I included a JavaScript script that alerts the user with instructions when the page loads via the onload event handler in the
<window>tag.
Play with this example and see how it works. Notice that the image you click on to start dragging it around doesn't come to the front. You might try to add code that does this (perhaps removing the target DOM node and reattaching it -- which would have the effect of putting that node at the bottom of the "list" and thusly on top).
I created this example also with the idea that you might take it and create your own XUL applications.
Final thoughts
The <bulletinboard> tag is fairly simple and straightforward, but it's very useful as a way to indicate that you want its child elements to be positioned much as standard DHTML does. But instead of using CSS position:absolute, you merely need to indicate an element's top and left attribute.
You cannot currently control the z-index directly, but you can indirectly by changing the order of a <bulletinboard> element's children. The possibilities for XUL-based applications based on <bulletinboard> are very interesting, and if you begin to get really sophisticated and start mixing in <grid>, <stack>, <deck>, and other tags, you might even come up with something new and astonishing.
This is the real power of XUL. It makes creating user interfaces easy, fun, and simple. Have fun exploring the <bulletinboard> tag and let me know what you come up with!
Andrew Wooldridge is a XUL and JS developer at Netscape Communications Corp.
Discuss this article in the O'Reilly Network Browsers Forum.
Return to the Mozilla DevCenter.




