Cross-Browser DHTML: Syntax Patching
October 25, 1998
Meta DHTML Part I: Syntax Patching
In the previous section we saw one technique for accounting
for syntactical differences between DOM's, the simple
hybrid using a mini-fork. When we talk about differing
syntaxes it is important to understand that in these scenarios
both DOM's support the same behavior, simply using a different
construction. Fortunately, both DOM's do share many
equal behaviors; for example, besides changing the background
color of a content block we could change its position
or size with ease. But again, we must use different syntaxes
for each browser.
An alternative approach to forking when syntax is the only
obstacle is "syntax patching". This concept
is easier to demonstrate than explain, but let's begin by
understanding the key point. In JavaScript, which is
the language you typically use to manipulate DHTML, there
is a method known as eval(). The eval()
method accepts a string parameter and it executes that string
as a JavaScript statement. The table below illustrates
some usages of eval():
| eval("alert('Testing');"); |
executes |
alert('Testing'); |
Pops up an alert box. |
| eval("hello"); |
executes |
hello |
By itself, not a legal statement and will
produce an error. |
obj = "layer";
eval("document." + obj + "['id']"); |
executes |
document.layer['id'] |
Netscape syntax to reference a content block. |
Understanding the usage of eval(), then, we
could imagine a technique as illustrated below:
<SCRIPT LANGUAGE = "JavaScript">
if (document.all) //MSIE
{ obj = "document.all";
bgcolor = ".style.backgroundColor";
left = ".style.pixelLeft";
top = ".style.pixelTop";
width = ".style.pixelWidth"; }
else //Netscape
{ obj = "document.layers";
bgcolor = ".bgColor";
left = ".left";
top = ".top";
width = ".clip.width";}
//Move object named 'block' to Y coordinate 100 and set
background color to white
objName = "['block']";
eval(obj + objName + top + " = 100;");
eval(obj + objName + bgcolor + " = 'white';");
</SCRIPT>
If the example script seems intimidating, it actually
isn't as messy as it appears upon closer inspection. We're
dealing with fragments here with the goal of building a
new common vocabulary for use with either browser's DOM.
The first half of the script is contained within an
if...else clause. This familiar fork outlines two
scenarios:
the browser supports the all object, and therefore
is Internet Explorer, or else is Netscape. In either
case, we define this new common vocabulary in coordination
with the proper syntax for that browser's DOM. We've
defined five new keywords: obj, bgcolor, left, top,
and width. Each of these keywords contains a
string fragment containing proper syntax for its DOM.
Once this new common vocabulary has been setup, we use the
eval() method to string together the
fragments into an action statement which yields some results.
In this example, the content block's Y coordinate
is moved to 100 pixels and its background color is set to white.
This action does not need to know which browser
it is operating within because we've already taken care of that
problem by creating the common vocabulary. The
chart below illustrates the actual statements executed by the
eval() examples:
| Internet Explorer |
|
|
| eval(obj + objName + top + " = 100;"); |
executes |
document.all['block'].style.pixelTop = 100; |
| eval(obj + objName + bgcolor + " = 'white';"); |
executes |
document.all['block'].style.backgroundColor = 'white'; |
| Netscape |
|
|
| eval(obj + objName + top + " = 100;"); |
executes |
document.layers['block'].top = 100; |
| eval(obj + objName + bgcolor + " = 'white';"); |
executes |
document.layers['block'].bgColor = 'white'; |
The main advantage to using syntax patching is that
you don't need to fork every DHTML action into two versions.
Rather, you use a fork at the beginning of your code
to create the common vocabulary. Once this is set, you can
simply use eval() methods to work with
this vocabulary, regardless of browser. The flexibility of
this approach rests largely on how thoroughly you create
the common vocabulary; meaning, how much of the DOM does
it cover. In our example we cover merely a handful of
properties of a couple of objects. The entire DOM's encompass
hundreds of properties across tens of objects -- defining
a common vocabulary for the entire DOM is unlikely. Typically,
you use this common vocabulary to cover those objects and
properties that your DHTML code is most likely to employ;
for instance, moving content blocks around the page primarily
leverages the layer (Netscape) or style
(MSIE) objects, as we've seen in our example.
In the section title we referred to syntax patching as
a type of "Meta DHTML." The reason is that
we've essentially created a new language layer atop the
existing DOM languages. Imagine, as an analogy, devising
a language which could be understood by both French and
Spanish speakers. We could call this language "Spench."
The Spench word for a house might be "Boda." In
the Spench-French dictionary, "boda" is defined
as "maison," while in the Spench-Spanish dictionary
"boda" is defined as "casa."
So, when you speak to a French or a Spanish person in Spench
you need only say "boda" and they will each
know what you mean.
The fictional Spench, then, is a meta-language. Similarly, we
have used the concept of a meta-language to bridge
the gap between the two DOM's of Microsoft and Netscape.
Cross-Browser DHTML: Simple Hybrid
Cross-Browser DHTML
Cross-Browser DHTML: Function Libraries
|