CBE Core Object Model | Cross-Browser.com |
CBE Core Object ModelImplementing W3C DOM2 InterfacesThe IdeaWhen I started working on the second version of CBE, I began to rethink the interface. By that I mean the names of the functions and objects, and how they relate to each other. Most of the other API's I studied had proprietary interfaces. They had function names like getX(), setX(), etc. There's nothing wrong with this type of interface - in fact I really liked it. So I began to think about what to name my functions, but I didn't want to use the names someone else had already used. Well... I'm not really good at coming up with cool names ;) During this time, I was studying the W3C recommendations. I suddenly realized - all the names were there, already created for me! And not only that, but they provided a complete object model specification. I then decided that, somehow, my API should not only use the names from the W3C recommendations, but attempt also to actually implement their object model interfaces in cross-browser Javascript. CBE 4 is a partial implementation of some of the W3C DOM2 interfaces. This document discusses the CBE core object model. The CBE event model is discussed in another document. The Implementation ObjectThe following is a very simple example of programming DHTML in a DOM1 environment. Listing 1 window.onload = function() { var e1 = document.getElementById('E1'); e1.style.left = 100 + 'px'; e1.style.top = 100 + 'px'; e1.style.visibility = 'visible'; } Now look at the following which uses CBE. It accomplishes the same task - positions an element at the point (100,100) and makes it visible. But this will work the same in all the different browsers CBE supports. And that's the whole purpose of CBE - to provide a programming interface as close as possible to the standard, while providing consistent, cross-browser semantics and rendering. Listing 2 function windowOnload() { var e1 = document.getElementById('E1'); e1.cbe.left(100); e1.cbe.top(100); e1.cbe.visibility('visible'); } I'm sure you see the differences between the two code listings.
CBE provides some shortcut methods. The following accomplishes the same as Listings 1 and 2, but is written the way I would normally program with CBE. Listing 3 function windowOnload() { var e1 = cbeGetElementById('E1').cbe; e1.moveTo(100,100); e1.show(); } CrossBrowserElementThe CrossBrowserElement object is a partial implementation of the DOM2 Element interface. It is a subclass of CrossBrowserNode, and so inherits those properties and methods. CrossBrowserElement objects populate the CBE Object Tree. A CrossBrowserElement object is created for each DIV or SPAN with id!="" and added to it's associated Element object as a property named cbe. The window.onload event is received by a function in cbe_core.js. It calls the function cbeInitialize(), which creates the CBE object model. Consider the following HTML. <div id='E1' class='clsCBE'>This is e1</div> Now notice the difference between accessing the native Element object and the CrossBrowserElement object, and then compare this with listing 3. Listing 4 function windowOnload() { // ne is a reference to the native Element object var ne = document.getElementById('E1'); /* e is a reference to the CrossBrowserElement object associated with the native Element object whose id is 'E1' */ var e = ne.cbe; e.moveTo(100,100); e.show(); } The CBE Object TreeThe function cbeInitialize() connects all the CrossBrowserElement objects into a tree structure using property names from the DOM2 Node interface. This tree structure models the parent/child (nesting) relationships among the CrossBrowserElement objects. When cbeInitialize() has finished creating the object model, it calls windowOnload(), if you have defined it. The window.onunload event is also received by a CBE function. It first calls windowOnunload(), if you have defined it, then nulls the cbe property of each positioned Element. The following illustrates the tree structure that is created for the HTML in listing 5. Notice that there are two additional CrossBrowserElement objects in the tree. One is associated with the native window object, and the other is associated with the native document object. Their respective id's are the values of the variables window.idWindow and window.idDocument.
There are common terms used to describe the relationships between objects in a tree structure. In the descriptions below I'll refer to the tree built from listing 5.
CrossBrowserNodeThe CrossBrowserNode object is a partial implementation of the DOM2 Node interface. It's properties provide for the implementation of the CBE Object Tree. CrossBrowserNode Properties:
In CBE, childNodes is an integer, and is simply the number of child nodes. The remaining properties point to CrossBrowserElement objects. With the CrossBrowserNode properties you can traverse (walk) the tree, that is, visit (apply a function to) each node in the tree (or sub-tree). I've also provided a function named cbeTraverseTree() which will perform a pre-order traversal of the entire tree (or sub-tree). If you need post-order traversal let me know and I'll provide that function. For the following example, imagine that the nodes P1 and P2 are containers for a dhtml window. Within them may be many different positioned elements, nested at different levels. When the user clicks anywhere within the container we want to raise the container's z-index, to make it come to the top of any other windows. The following function would be useful, and it makes use of the CrossBrowserNode properties and the tree structure. Listing 6 function getTopContainer(oThis) { var ancestor = oThis; while (ancestor.id != window.idDocument) { ancestor = ancestor.parentNode; } return ancestor; } ClientSnifferJrThere is one ClientSnifferJr object, named is. It is the client detection object, which is available immediately after cbe_core.js has loaded. With the is object you can determine which browser your page is currently running on. Listing 7 function windowOnload() { var s = "Welcome "; if (is.opera) s += "Opera"; else if (is.gecko) s += "Gecko"; else if (is.nav) s += "Navigator"; window.defaultStatus = s + " User!"; } See the object reference for a complete list of events, properties and methods for all the objects discussed in this document. |