<?xml version="1.0" encoding="ISO-8859-1" ?>
<?xml-stylesheet type="text/xsl" href="/lib/xsl/devedge-1.00/article_en.xsl"?>
<nde:article 
  url="/viewsource/2003/devedge-redesign-js/"
  xmlns="http://www.w3.org/1999/xhtml"
  xmlns:nde="http://devedge.netscape.com/2002/de"
  xmlns:ent="http://devedge.netscape.com/2003/ent"
  xml:lang="en">

<nde:header>
  <nde:title>Netscape DevEdge Redesign: JavaScript</nde:title>
  <nde:category>Article</nde:category>
  <nde:authlist>
    <nde:author>
      <nde:authname>Bob Clary</nde:authname>
      <nde:authaffil>Netscape Communications</nde:authaffil>
    </nde:author>
  </nde:authlist>
  <nde:pubdate year="2003" month="02" day="11"/>
  <nde:channels>
    <nde:channel id="viewsource" />
    <nde:channel id="dom" />
    <nde:channel id="javascript" />
  </nde:channels>
  <nde:keywords>netscape, devedge, javascript, redesign, dhtml, dhtml menus, css, code sample, gecko</nde:keywords>
  <nde:summary>
    Learn about the use of JavaScript in Netscape's DevEdge which
    is used to extend pure CSS-based menus to support most modern
    browsers.
  </nde:summary>
</nde:header>

<nde:content>

  <h2 id="introduction">Introduction</h2>

  <p>
    The initial launch of 
    DevEdge (<code>http://devedge.netscape.com/</code>) 
    as a separate site from the 
    DevEdge Archive (<code>http://developer.netscape.com/</code>) 
    in August 2002 maintained a great degree of compatibility with 
    legacy browsers such as Netscape Communicator 4.x and Internet Explorer 4.x.
    This backward compatibilty however limited the nature of the site's
    design and prevented the use of more advanced features.
  </p>

  <p>
    One of the goals of the 
    <a href="/viewsource/2003/devedge-redesign/">Netscape DevEdge Redesign</a>
    was to illustrate how the W3C web standards can benefit web developers. 
    Backward compatibility with older browsers was not a goal 
    and has opened the door to adding some interesting
    features which illustrate the possibilities of advanced CSS and JavaScript. 
  </p>

  <h2>Menus</h2>

  <p>
    One of the more popular uses of Dynamic HTML is to provide a rich 
    navigation interface for web sites through the use of menus. Many different 
    implementations of Dynamic HTML menus are available.
  </p>

  <p>
    Typical menus implemented using Dynamic HTML have fairly large footprints, require
    visitors to enable JavaScript, are constructed on the fly, are not accessible
    and are difficult for average web authors to implement and maintain. For these as well
    as other reasons, many sites do not offer a rich navigation interface to their visitors.
  </p>

  <p>
    We decided that using standards to implement a re-usable, maintainable and 
    accessible menu for DevEdge would help educate web developers about the benefits 
    of standards-based web development.
  </p>

  <h2 id="purecssmenus">Pure CSS Menus</h2>

  <p>
    During 2002 <a href="http://www.meyerweb.com/eric/css/edge/menus/demo.html">Eric A. Meyer</a>,
    <a href="http://www.alistapart.com/stories/taminglists/">Mark Newhouse</a> and others began 
    investigating the use of unordered lists and CSS to provide navigational help on web sites.
    This lead to the idea of implemented menus using only
    CSS 2 without the need for cross-browser JavaScript. 
    This was possible for the first time due to the level of support achieved for
    the necessary features of CSS 2 in Netscape Gecko-based<ent:trade/> browsers such as 
    Mozilla 1.0 and Netscape 7.x. 
  </p>

  <p>
    The possibility of providing the rich experience of Dynamic HTML without having to 
    worry about cross-browser JavaScript issues with the added advantages of easy maintainance
    and increased accessibility were compelling reasons to investigate the use
    of pure CSS menus on DevEdge.
  </p>

  <h3 id="example-1">Example 1 - Pure CSS Menu</h3>

  <p>
    This example uses an unordered list containing the choices for 
    a simple one-level pull down menu. CSS rules are applied to 
    the unordered list through the use of the class name <code>nde-menu-system</code> 
    and submenus are identified via the use of the class name <code>submenu</code>.
  </p>

  <p>
    <a href="examples/example-1.html" title="Example 1 - Pure CSS Menu">Click to view Example 1</a>
  </p>

  <pre><![CDATA[
<ul class="nde-menu-system">
  <li><a href="#">Link</a></li>
  <li class="submenu">
    <a href="#">Submenu</a>
    <ul>
      <li><a href="#">Subitem 1</a></li>
      <li><a href="#">Subitem 2</a></li>
    </ul>
  </li>
</ul>
]]></pre>

  <p>
    The basic layout and functionality of the menu are achieved through CSS
    rules which display the top-level list items inline, while
    attaching different CSS rules to submenus through the use of CSS 2 
    <code>:hover</code> rules which are responsible for opening 
    and closing the submenus. Other CSS rules serve the role of smoothing
    out the differences in the implementation of the CSS 2 specification
    between Netscape Gecko, Opera and Internet Explorer.
  </p>

  <h4>Browser Comparison</h4>

  <p>
    Netscape Gecko-based browsers such as Netscape 7.x and Mozilla
    on all platforms as well as Opera 7 on Windows display the top-level items 
    inline and open and close the submenu when the mouse hovers over the
    top-level <code>Submenu</code> item.
  </p>
  
  <p>
    Note that Netscape 7.x
    requires the <code>top</code> be set in the <code>ul.nde-menu-system li ul</code>
    css rule in order to position the submenus properly. You may need to adjust
    this value if you reuse this example on your own site.
    Note also the difference in appearance between Netscape Gecko-based browsers 
    and Opera 7.
  </p>

  <p>
    Netscape 6.x on all platforms and Internet Explorer 5.5+ on Windows can display the top-level items 
    inline however due to their lack of support for <code>:hover</code> 
    on arbitrary elements they can not display the submenu.
  </p>

  <p>
    Pure CSS menus have some compelling advantages:
  </p>

  <ul>
    <li>Ease of maintenance</li>
    <li>Accessibility</li>
    <li>Lightweight</li>
    <li>Navigation still possible in downlevel browsers which do not support CSS 2</li>
    <li>Not dependant upon JavaScript being enabled</li>
  </ul>

  <p>
    Pure CSS menus also have disadvantages:
  </p>

  <ul>
    <li>
      <p>
        Lack of full support by Internet Explorer
      </p>
    </li>
    <li>
      <p>
      Differences between the implementations of CSS 2 in
      different browsers can lead to differences in appearance
      and behavior in pages with layout more complicated than
      our simple example 
      such as the redesigned pages on DevEdge.
    </p>
    <p>
      To see this in action, open Netscape 7.01, disable
      JavaScript and load DevEdge. Note how the menus at the
      top of the page continue to work without serious degradation. 
      Then open Opera 7, disable JavaScript and load DevEdge. 
      Note how the submenus open displaced much farther down the
      page.
    </p>
    </li>
  </ul>

  <h2 id="hybridcssmenus">Hybrid CSS-JavaScript Menus</h2>

  <p>
    While the promise of pure CSS menus was compelling, the actual 
    behavior of the browsers which visit DevEdge would mean that many of our
    visitors would not receive a positive experience if we relied solely on 
    CSS to implement our menus. 
  </p>

  <p>
    A compromise approach was reached where we would provide a pure CSS menu
    which could be used by any CSS 2 capable browser without JavaScript enabled
    but would use JavaScript to emulate the CSS 2 features which 
    were lacking in Internet Explorer and other browsers. At the same time, 
    JavaScript could be used to smooth over implementation differences between
    CSS 2 compliant browsers.
  </p>

  <p>
    The main features of CSS which needed to be emulated in JavaScript are:
  </p>

  <dl>
    <dt>Selectors</dt>
    <dd>
      <p>
        Selectors in CSS determine to which elements specific CSS rules 
        are applied. JavaScript and the W3C DOM Core API can be easily used
        to walk the unordered list and to apply specific style rules
        using the W3C DOM Style APi.
      </p>
    </dd>
    <dt>:hover on arbitrary elements</dt>
    <dd>
      <p>
        <code>:hover</code> CSS rules can be emulated through the use of 
        mouseover and mouseout event handlers implemented in JavaScript 
        attached to the appropriate elements. These event handlers can
        use the W3C DOM Core, DOM Style APIs to manipulate the appearance
        and structure of a document to reproduce the same behavior as
        accomplished through pure CSS.
      </p>
    </dd>
  </dl>

  <h3 id="example-2">Example 2 - Hybrid CSS-JS Menu</h3>

  <p>
    <a href="examples/example-2.html" title="Example 2 - Hybrid CSS-JS Menu">Click 
      to open Example 2</a>
  </p>

  <pre><![CDATA[
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
                      "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<link rel="stylesheet" type="text/css" href="cssjsmenudhtml.css">
<link rel="stylesheet" type="text/css" href="cssjsmenuhover.css" id="hoverJS">
<script type="text/javascript" src="dhtml.js"></script>
<script type="text/javascript" src="cssjsmenu.js"></script>
<script type="text/javascript">
  <!--
  function init()
  {
    cssjsmenu('navbar');
    if (document.getElementById)
    {
      var kill = document.getElementById('hoverJS'); 
      kill.disabled = true;
    }
  }
  // -->
</script>
</head>
<body onload="init()">

  <h1>Example 2 - Hybrid CSS-JS Menu</h1>
  <div id="navbar">
    <ul class="nde-menu-system">
      <li><a href="#">Link</a></li>
      <li class="submenu">
        <a href="#">Submenu</a>
        <ul>
          <li><a href="#">Subitem 1</a></li>
          <li><a href="#">Subitem 2</a></li>
        </ul>
      </li>
    </ul>
  </div>

</body>
</html>]]></pre>
  
  <p>
    This example extends Example 1 by 
  </p>

  <ul>
    <li>
      <p>
        Separating the CSS rules into two different external stylesheets:
        cssjsmenudhtml.css and cssjsmenuhover.css. 
      </p>
      <p>
        <a href="examples/cssjsmenudhtml.css">cssjsmenudhtml.css</a> contains the basic
        rules which define the menu.
      </p>
      <p>
        <a href="examples/cssjsmenuhover.css">cssjsmenuhover.css</a> contains only those rules 
        related to <code>:hover</code> effects. Note the work around for Internet Explorer's 
        bug where it propagate events into elements which simply visually cover other elements
        but do not contain them.
      </p>
      <p>
        This separation allows browsers with JavaScript enabled to disable the stylesheet 
        containing the CSS <code>:hover</code> rules and to replace them with equivalent behavior 
        implemented using event handlers. Disabling the CSS <code>:hover</code> behavior 
        when using the JavaScript version of the hybrid menu is important since there can 
        be unwanted interactions if both are active at the same time.
      </p>
    </li>
    <li>
      <p>
        Placing a <code>DIV</code> with <code>ID</code> attribute around the <code>UL</code>
        containing the menu. This allows the menu to be quickly located using the W3C DOM Core
        <code>document.getElementById()</code> method.
      </p>
    </li>
    <li>
      <p>
        Incorporating two different external JavaScript files which are used to implement
        the JavaScript implementation of the hybrid CSS-JS menu: dhtml.js and cssjsmenu.js.
      </p>
      <dl>
        <dt><a href="examples/dhtml.js">dhtml.js</a></dt>
        <dd>
          <p>
            contains several functions which are used to get and set element positions and to determine
            whether one element contains another. Note that the non-standard 
            properties <code>HTMLElement.offsetLeft</code>, <code>HTMLElement.offsetTop</code>,
            <code>HTMLElement.offsetParent</code> are used to obtain the position of elements
            on the page. Although these properties were initially introduced by Microsoft Internet Explorer
            and are not standard, they are supported by Netscape Gecko-based browsers as 
            well as Opera 7 and are quite useful.
          </p>
        </dd>
        <dt><a href="examples/cssjsmenu.js">cssjsmenu.js</a></dt>
        <dd>
          <p>
            contains the main function used to convert a pure CSS Menu into a Hybrid CSS-JS Menu.
            The function <code>cssjsmenu(menuid)</code> locates the <code>DIV</code> which contains
            the menu's unordered list, walks down the DOM of the unordered list converting the
            style attributes of the <code>UL</code> and <code>LI</code> elements into a form which
            can be used by the <code>mouseover</code> and <code>mouseout</code> event handlers, and
            attaches the appropriate event handlers to mimic the <code>:hover</code> CSS rules.
          </p>
        </dd>
      </dl>
    </li>
    <li>
      <p>
        Defining an <code>onload</code> event handler which will call the <code>cssjsmenu</code>
        function to enable the JS-based menu and to disable the stylesheet containing the 
        pure CSS Menu's <code>:hover</code> rules.
      </p>
    </li>
  </ul>

  <h4>Browser Comparison</h4>

  <p>
    Note that the Hybrid CSS-JS Menu is supported by Netscape Gecko-based browsers
    Netscape 6.x, Netscape 7.x and Mozilla 0.9.4+ (All platforms),
    Opera 7 (Windows) and Internet Explorer 5.5+ (Windows). 
  </p>
    
  <h3 id="example-3">Example 3 - Hybrid CSS-JS Menu with Style</h3>

  <p>
    <a href="examples/example-3.html" title="Example 3 - Hybrid CSS-JS Menu with Style">Click 
      to open Example 3</a>
  </p>

  <pre><![CDATA[
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
                      "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<link rel="stylesheet" type="text/css" href="cssjsmenudhtml.css">
<link rel="stylesheet" type="text/css" href="cssjsmenuhover.css" id="hoverJS">
<link rel="stylesheet" type="text/css" href="cssjsmenustyle.css"">
<script type="text/javascript" src="dhtml.js"></script>
<script type="text/javascript" src="cssjsmenu.js"></script>
<script type="text/javascript">
  <!--
  function init()
  {
    cssjsmenu('navbar');
    if (document.getElementById)
    {
      var kill = document.getElementById('hoverJS'); 
      kill.disabled = true;
    }
  }
  // -->
</script>
</head>
<body onload="init()">

  <h1>Example 3 - Hybrid CSS-JS Menu with Style</h1>
  <div id="navbar">
    <ul class="nde-menu-system">
      <li><a href="#">Link</a></li>
      <li class="submenu">
        <a href="#">Submenu</a>
        <ul>
          <li><a href="#">Subitem 1</a></li>
          <li><a href="#">Subitem 2</a></li>
        </ul>
      </li>
    </ul>
  </div>

</body>
</html>]]></pre>
  
  <p>
    This example extends Example 2 by adding another stylesheet, 
    <a href="examples/cssjsmenustyle.css">cssjsmenustyle.css</a> to customize 
    the appearance of the menu and menu items. 
  </p>

  <h2 id="devedgeuse">How the Hybrid CSS-JS Menu is used on DevEdge</h2>

  <p>
    DevEdge uses the Hybrid CSS-JS Menu to implement both the pull-down menu
    found at the top of every page and the customize menu which allows visitors
    to select their favorite themes.
  </p>

  <h2 id="conclusion">Conclusion</h2>

  <p>
    Hybrid CSS-JS menus provide a light-weight, accessible, easily maintained
    method of adding simple pull-down menus to your site. Please feel free to
    reuse these menus on your own site.
  </p>

  <p>
    There are many different approaches to providing modern browsers with dynamic
    menus. For additional study, I recommend 
    <a href="http://brainjar.com/dhtml/menubar/">BrainJar.com's Menu Bar</a> and
    <a href="http://www.gazingus.org/dhtml/?id=109">gazingus.org's Using Lists for DHTML menus</a>.
  </p>

  <h2 id="download">Download Examples</h2>
    <p>
      <a href="/viewsource/2003/devedge-redesign-js/examples/devedge-redesign-js.zip">
        devedge-redesign-js.zip (7K)</a>
    </p>

</nde:content>


<nde:related area="nde">
 <nde:item url="/viewsource/2003/devedge-redesign/">DevEdge Redesigns As a Standards Showcase</nde:item>
 <nde:item url="/viewsource/2003/devedge-redesign-css/">Netscape DevEdge Redesign: CSS</nde:item>
 <nde:item url="/central/javascript/">JavaScript Central</nde:item>
 <nde:item url="/central/css/">CSS Central</nde:item>
 <nde:item url="/central/dom/">DOM Central</nde:item>
</nde:related>

<nde:related area="ext">
    <nde:item url="http://www.alistapart.com/stories/taminglists/">Taming Lists by Mark Newhouse</nde:item>
    <nde:item url="http://www.meyerweb.com/eric/css/edge/menus/demo.html">pure CSS menus by Eric A. Meyer</nde:item>
    <nde:item url="http://brainjar.com/dhtml/menubar/">BrainJar.com's Menu Bar</nde:item>
    <nde:item url="http://www.gazingus.org/dhtml/?id=109">gazingus.org's Using Lists for DHTML Menus</nde:item>
</nde:related>

</nde:article>
