Recommendations for JavaScript drop-down menu code
|
|
Thread rating:  |
Brian Adkins - 27 Sep 2007 17:04 GMT I would appreciate recommendations for JavaScript code that implements drop-down, hierarchical menus. Are there high quality libraries for this, or is it more typical for people to roll their own?
My preference is for open source code, but royalty-free commercial code would be acceptable as well.
Ideally, the code would: * Allow configuring horizontal or vertical menus * Allow configuring the delay for closing the menu after mousing out of the menu * Provide a mechanism for playing well with existing code and other libraries * Be well designed & documented * Be highly portable among browsers in common use * Allow styling via css
Thanks, Brian Adkins
David Mark - 27 Sep 2007 17:53 GMT > I would appreciate recommendations for JavaScript code that implements > drop-down, hierarchical menus. Are there high quality libraries for > this, or is it more typical for people to roll their own? I don't know if there are any good ones out there, but there are lots of bad ones.
> My preference is for open source code, but royalty-free commercial > code would be acceptable as well. > > Ideally, the code would: > * Allow configuring horizontal or vertical menus That is a function of CSS, not script.
> * Allow configuring the delay for closing the menu after mousing out > of the menu That doesn't make sense to me for a hierarchical menu.
> * Provide a mechanism for playing well with existing code and other > libraries > * Be well designed & documented > * Be highly portable among browsers in common use Your expectations of freebie menu scripts are likely too high.
> * Allow styling via css You'd be hard-pressed to disallow CSS with script.
Anyway, craate your hierarchy with nested lists, style it with CSS and then look for a script that initially hides all but the parent list and then displays child lists in response to mouse or keyboard input (you'll find that most ignore the keyboard.)
Brian Adkins - 28 Sep 2007 18:49 GMT > > My preference is for open source code, but royalty-free commercial > > code would be acceptable as well. [quoted text clipped - 3 lines] > > That is a function of CSS, not script. There are a number of ways of accomplishing this. CSS is one way, but the JavaScript code can make CSS styling less difficult or more difficult.
> > * Allow configuring the delay for closing the menu after mousing out > > of the menu > > That doesn't make sense to me for a hierarchical menu. It makes even more sense for a hierarchical menu. Consider navigating through a complicated menu structure via hovering, then right before you click the appropriate entry, you accidentally move the mouse too far and the whole menu closes. That's the scenario (typically found on CSS-only menus) I want to avoid, so I'd like a "grace period" if you will.
> > * Provide a mechanism for playing well with existing code and other > > libraries > > * Be well designed & documented > > * Be highly portable among browsers in common use > > Your expectations of freebie menu scripts are likely too high. If so, then a commercial solution would seem to make sense. Do you know of good commercial menus?
> > * Allow styling via css > [quoted text clipped - 4 lines] > and then displays child lists in response to mouse or keyboard input > (you'll find that most ignore the keyboard.) If I was only looking for that, I'd just write it myself, but I'm not big on reinventing wheels.
David Mark - 28 Sep 2007 18:56 GMT > > > My preference is for open source code, but royalty-free commercial > > > code would be acceptable as well. [quoted text clipped - 7 lines] > the JavaScript code can make CSS styling less difficult or more > difficult. How so? Your app must not break down when either or both is disabled.
> > > * Allow configuring the delay for closing the menu after mousing out > > > of the menu [quoted text clipped - 7 lines] > CSS-only menus) I want to avoid, so I'd like a "grace period" if you > will. I didn't mean the delay made no sense, but the usual rollover-only functionality of canned menu scripts.
> > > * Provide a mechanism for playing well with existing code and other > > > libraries [quoted text clipped - 17 lines] > If I was only looking for that, I'd just write it myself, but I'm not > big on reinventing wheels. If you aren't looking for what I described, then what are you looking for?
Brian Adkins - 28 Sep 2007 19:12 GMT > > > > Ideally, the code would: > > > > * Allow configuring horizontal or vertical menus [quoted text clipped - 6 lines] > > How so? Your app must not break down when either or both is disabled. "Must not" ? I'm surprised you think you know enough about the requirements for my application to be able to make this statement. The title of this post has to do with recommending JavaScript menus. If you're not going to make a recommendation, please don't also make such ridiculous statements. Combining arrogance and ignorance is inadvisable.
Before you reply with some ridiculous retort, please identify at least 3 major web applications that would practically fall apart if users disabled both JavaScript & CSS and reconcile that with your statement above.
> > > > * Allow configuring the delay for closing the menu after mousing out > > > > of the menu [quoted text clipped - 10 lines] > I didn't mean the delay made no sense, but the usual rollover-only > functionality of canned menu scripts. I can see you have many opinions. It's a pity none of them have to do with the original request.
David Mark - 28 Sep 2007 19:40 GMT > > > > > Ideally, the code would: > > > > > * Allow configuring horizontal or vertical menus [quoted text clipped - 9 lines] > "Must not" ? I'm surprised you think you know enough about the > requirements for my application to be able to make this statement. The It has nothing to do with the requirements of your application. That's a general rule for any competent Web page or application.
> title of this post has to do with recommending JavaScript menus. If > you're not going to make a recommendation, please don't also make such > ridiculous statements. Combining arrogance and ignorance is > inadvisable. The specific response was to your assertion that JS and CSS are somehow intertwined. It should be intuitively obvious that if you disable one but not the other, then any reliance on JS to prop up CSS will be exposed. It is inadvisable to argue a point that you clearly don't understand.
> Before you reply with some ridiculous retort, please identify at least > 3 major web applications that would practically fall apart if users > disabled both JavaScript & CSS and reconcile that with your statement > above. As I suspected, you didn't get the point at all. Regardless, most Web applications (and many simple Web pages) fall apart when both JS and CSS are disabled. Name three "major Web applications" that don't.
> > > > > * Allow configuring the delay for closing the menu after mousing out > > > > > of the menu [quoted text clipped - 13 lines] > I can see you have many opinions. It's a pity none of them have to do > with the original request. The original request matters little at this point. As I mentioned a few posts back, I have no recommendation for you, other than a few general rules to follow when evaluating canned menu scripts.
Peter Michaux - 29 Sep 2007 01:35 GMT > > > > > > Ideally, the code would: > > > > > > * Allow configuring horizontal or vertical menus [quoted text clipped - 12 lines] > It has nothing to do with the requirements of your application. > That's a general rule for any competent Web page or application. It does have to do with the specific requirements. Not all web pages are for general web consumption. Some are for back-end pages where the user logs in and is known to have a certain set of prerequisite capabilities. In these cases, spending the extra time to make the page degrade gracefully or otherwise may not be considered a wise use of development dollars.
Another option is a gateway page that branches to two versions of the application. This is like GMail. One branch is for JavaScript enabled (and sufficiently capable JavaScript) and the other branch is for anyone not capable of the "full" version. So in this case the fancy drop down menus would not have to degrade either.
Peter
David Mark - 30 Sep 2007 00:37 GMT > > > > > > > Ideally, the code would: > > > > > > > * Allow configuring horizontal or vertical menus [quoted text clipped - 19 lines] > degrade gracefully or otherwise may not be considered a wise use of > development dollars. Correct, but popup menus are simple enough that you would just do them right in the first place.
> Another option is a gateway page that branches to two versions of the > application. This is like GMail. One branch is for JavaScript enabled Please don't use Google as an example. Google throws JS errors at me constantly. But I get the idea. I don't like it, but I get it.
> (and sufficiently capable JavaScript) and the other branch is for > anyone not capable of the "full" version. So in this case the fancy > drop down menus would not have to degrade either. Fancy dropdown menus? Granted they aren't really necessary for most Web pages/applications, but they are fairly trivial widgets, which is one reason they are so prevalent.
Hierarchies of menus would seem an unwieldy choice for site navigation, but it is apparently the preferred UI for most Web developers. Unfortunately, most implementations have lousy usability and/or accessibility. It's as if the developers had never used menus in software applications. Of course, if they were paying attention to their desktops, they would have noticed that navigation is done with a tree, not a series of cascading menus.
Here is an example of how I think menus should work. The code is a little slapdash, but in my brief testing it functioned flawlessly. The default behavior does not popup top-level menus on rollovers (I hate that), but there is a global option to change this. And they don't vanish just because you move the mouse away (click to hide all active menus.) And yes, there is a configurable delay for hiding sub- menus when it makes sense to hide them. As for accessibility, keyboard users will have no problem and I think most screen readers/ aural browsers will work as well. I tested in IE7, the latest Mozilla and Netscape, Opera 9 and Windows Safari beta. IE7 in quirks mode had a weird issue with adding space between listitems when sub-menus open, but I haven't investigated that (you shouldn't use quirks mode anyway.) It should be okay in IE6 in standards mode.
The example has three menus with identical content: one styled as a horizontal menubar, one vertical and the other as a popup menu. The orientations are determined solely by CSS. The instantiation of the popup menu and positioning of child popups are functions of the script.
Use something like this and you won't need a branch page as the menus degrade gracefully without script as well as without script and style. As usual, the hardest case to get perfect is where script is enabled but style is not. The specific examples I used are admittedly lousy in this case as only the leaf nodes navigate, despite the fact that all nodes have perfectly good href's. So if you must use cascading menus for navigation (as opposed to commands), it is a good idea to relegate links to leaf nodes.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/ TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Menus</title> <style type="text/css" media="all"> ul.menubar { list-style-type:none;padding:0;margin:0 } ul.menubar a, ul.menuPopup a { padding: 0 .25em 0 .25em } ul.menubar li { margin:0;padding:0;display:inline} ul.menubar li a:link, ul.menubar li a:visited { text-decoration:none } ul.menubar li a:hover { background-color:#0000DD;color:white } ul.menuPopup { list-style-type:none;padding:0;margin:0;border:outset 2px;background-color:threedface;color:windowtext;z-index:1 } ul.menuPopup li { white-space:nowrap;display:block } ul.menuPopup li a:link, ul.menuPopup li a:visited { text- decoration:none;display:block } ul.menuPopup li a:hover { background- color:#0000DD;color:white;display:block } ul.menuPopup li a.popup:after { content: "\0020\00BB"; }
#myMenubarVertical.menubar { width:5em;margin-bottom:1em } #myMenubarVertical.menubar li, #myMenubarVertical.menubar li a { display:block } #testPopupMenu { display:block; margin-top:1em }
body {font-family:sans-serif;background-color:threedface} </style> <!--[if IE]> <style type="text/css" media="all"> ul.menubar { display:inline-block } /* Adds layout to fix IE relative positioning bug </style> <![endif]--> <style type="text/css" media="handheld"> body { margin:4px } </style> <style type="text/css" media="print"> body {font-family:serif} ul.menubar, ul.menuPopup { list-style-type:disc;padding:0 0 0 1em } ul.menuPopup { border:none;background- color:white;color:black;position:static !important;display:block ! important } ul.menuPopup li a {color:black;background-color:inherit} ul.menuPopup li a.popup:after { content: ""; } #testPopupMenu { display:none } </style> <script type="text/javascript"> var global = this; if (this.document && this.document.getElementsByTagName && this.document.getElementById) { (function() { var html = global.document.getElementsByTagName('html'); if (html && html[0] && html[0].style && typeof(html[0].style.visibility) == 'string') { global.document.write('<style type="text/css" media="all">#myMenubar, #myMenubarVertical, #myPopupMenu, #testPopupMenu { visibility:hidden }<\/style>'); } })();
this.onload = function() { // Global options var menuPause = 500; // Delay before hiding/showing sub-menu var startWithRollover = false; // Default requires click to show initial top-level item (second click hides) // Set to true to allow rollover to show top-level menus (click navigates)
var doc = global.document; var el, elButton;
var activeMenu, timer, hrefTypeUnknown;
function nodeName(el) { var n = (el.tagName || el.nodeName); return n && n.toLowerCase(); }
function cancelPropagation(e) { e = e || global.event; if (e.stopPropagation) { e.stopPropagation(); } e.cancelBubble = true; }
function setStatus(s) { // Firefox unload/mouseover bug requires typeof check here if (typeof(global) != 'undefined') { global.setTimeout(function() { if (typeof(global) != 'undefined') { global.status = s; } }, 0); } return true; }
function menuRoot(list) { var root;
if (!list.parentNode || nodeName(list.parentNode) != 'li') { return null; } while (list.parentNode) { list = list.parentNode; if (list && nodeName(list) == 'ul') { root = list; } } return (root._isRootless)?null:root; }
function isAncestor(listChild, listParent) { while (listChild.parentNode && listChild.parentNode != document) { if (listChild.parentNode == listParent) { return true; } listChild = listChild.parentNode; } }
function hideActiveMenu(branch, root) { if (timer) { global.clearTimeout(timer); timer = null; } activeMenu.style.display = 'none'; var parentMenuItem = activeMenu.parentNode; if (parentMenuItem && nodeName(parentMenuItem) == 'li' && parentMenuItem.parentNode && parentMenuItem.parentNode != branch && parentMenuItem.parentNode != root) { activeMenu = parentMenuItem.parentNode; hideActiveMenu(branch, root); } activeMenu = branch || null; }
function showMenu(el, branch, side, pos) { if (timer) { global.clearTimeout(timer); timer = null; } var elOffset, elParent, tag, a;
side = side || 'bottom'; elParent = el.parentNode;
el.style.visibility = 'hidden'; el.style.display = 'block';
if (!pos && elParent && nodeName(elParent) == 'li') { pos = [0, 0]; if (elParent != branch) { elOffset = elParent; do { pos[0] += elOffset.offsetTop || 0; pos[1] += elOffset.offsetLeft || 0; if (elParent != elOffset) { pos[0] += elOffset.clientTop || 0; pos[1] += elOffset.clientLeft || 0; } elOffset = elOffset.offsetParent; if (elOffset) { tag = nodeName(elOffset); if (tag != 'li' && tag != 'ul') { break; } } } while (elOffset && elOffset != branch); } if (side == 'right') { pos[1] += elParent.offsetWidth || 0; } else { pos[0] += elParent.offsetHeight || 0; } } if (pos) { el.style.top = pos[0] + 'px'; el.style.left = pos[1] + 'px'; } el.style.visibility = 'visible';
if (activeMenu && !isAncestor(el, activeMenu) && activeMenu != el) { var root = menuRoot(activeMenu); hideActiveMenu((branch == root)?null:branch, root); }
activeMenu = el;
a = el.getElementsByTagName('a'); if (a[0] && a[0].focus) { a[0].focus(); } }
function showMenuPopup(el) { showMenu(el, null); }
function attachPopupActivator(el, list) { el.onclick = function(e) { if (list.style.display == 'none') { showMenu(list, null); } else { hideActiveMenu(null, null); } cancelPropagation(e); }; }
function initializeChildMenus(list, root, initialSide) { initialSide = initialSide || 'bottom'; if (typeof(root) == 'undefined') { root = list; } var lists, itemFocused; var anchors = list.getElementsByTagName('a'); var i = 0; var l = anchors.length; while (i < l) { if (anchors[i].parentNode) { lists = anchors[i].parentNode.getElementsByTagName('ul'); if (lists && lists[0]) { if (lists[0].style.display != 'none') { // already did this one? hrefTypeUnknown = typeof(anchors[i].href) == 'unknown'; if (root != list || !startWithRollover || (!hrefTypeUnknown && ! anchors[i].href)) { if (!hrefTypeUnknown) { anchors[i].href = anchors[i].href || '#'; } anchors[i].onclick = (function(el) { return function(e) { if (el.style.display == 'none') { showMenu(el, list, (root == list)? initialSide:'right'); } else { if (root == list) { hideActiveMenu((root == list)?null:list, root); } } cancelPropagation(e); return false; }; })(lists[0]);
} anchors[i].tabIndex = 0; initializeChildMenus(lists[0], root); anchors[i].onmouseover = (function(el) { return function(e) { if (this.title) { setStatus(this.title); } if ((!activeMenu && ! startWithRollover) || (activeMenu && isAncestor(activeMenu, el))) { return; } if (timer) { global.clearTimeout(timer); } timer = global.setTimeout(function() { showMenu(el, list, (root == list)? initialSide:'right'); }, (list == root)?0:menuPause); return true; }; })(lists[0]); anchors[i].onmouseout = function() { if (timer) { clearTimeout(timer); timer = null; } if (this.title) { return setStatus(''); } }; anchors[i].className = 'popup'; lists[0].className = 'menuPopup'; lists[0].style.position = 'absolute'; lists[0].style.display = 'none'; } } else { if (anchors[i].parentNode.parentNode && anchors[i].parentNode.parentNode.style.display != 'none') { // already did this one? anchors[i].onmouseover = function() { if (this.title) { setStatus(this.title); } if (timer) { global.clearTimeout(timer); timer = 0; } if (activeMenu && !isAncestor(this, activeMenu)) { timer = global.setTimeout(function() { hideActiveMenu((list == root)? null:list, menuRoot(activeMenu)); }, (list == root)?0:menuPause); } return true; }; anchors[i].onmouseout = function() { if (this.title) { return setStatus(''); } }; } } i++; } } if (l) { global.onunload = function() { i = 0; l = anchors.length; while(i < l) { anchors[i].onclick = anchors[i].onmouseover = anchors[i].onmouseout = null; i++; } }; } }
function documentClickHandler(list, root) { if (typeof(root) == 'undefined') { root = list; } return function() { if (activeMenu && (isAncestor(activeMenu, list) || activeMenu == list)) { hideActiveMenu(null, root); } }; }
function attachDocumentClickHandler(list, root) { var onclickOld = document.onclick; var onclickNew = documentClickHandler(list, root); document.onclick = (onclickOld)?function(e) { onclickOld(e); onclickNew(e); }:onclickNew; }
function initializeMenu(list, className, initialSide) { list.className = className || 'menubar'; list.style.position = 'relative'; initializeChildMenus(list, list, initialSide); attachDocumentClickHandler(list); }
function initializeMenuPopup(list, className) { list.className = className || 'menuPopup'; list._isRootless = true; initializeChildMenus(list, null); list.style.position = 'absolute'; list.style.display = 'none'; attachDocumentClickHandler(list, null); }
el = doc.getElementById('myMenubar'); if (el && el.parentNode && el.style && typeof(el.style.display) == 'string' && typeof(el.style.position) == 'string') { initializeMenu(el); el.style.visibility = 'visible'; el = doc.getElementById('myMenubarVertical'); if (el) { initializeMenu(el, null, 'right'); el.style.visibility = 'visible'; } el = doc.getElementById('myPopupMenu'); if (el) { initializeMenuPopup(el); el.style.visibility = 'visible'; elButton = document.getElementById('testPopupMenu'); if (elButton) { elButton.disabled = false; attachPopupActivator(elButton, el); elButton.style.visibility = 'visible'; } } }
}; } </script> </head> <body> <ul id="myMenubarVertical"><li><a title="Google sites" href="http:// www.google.com">Google</a><ul><li><a href="http:// www.gmail.com">GMail</a><ul><li><a href="http://www.gmail.com">Inbox</ a></li><li><a href="http://www.gmail.com">Outbox</a></li></ul></ li><li><a href="http://www.googlecode.com">Google Code</a><ul><li><a href="http://code.google.com/apis/ajaxsearch/">Google Ajax Search</a></ li><li><a href="http://www.google.com/apis/maps/">Google Maps</a></ li><li><a href="http://code.google.com/webtoolkit/">Google Web Toolkit</a></li></ul></li><li><a href="http://www.google.com/ talk">GTalk</a></li></ul></li><li><a href="http://www.msn.com" title="MSN sites">MSN</a><ul><li><a href="http://www.msnbc.com">News</ a></li><li><a href="http://msn.foxsports.com">Sports</a></li><li><a href="http://weather.msn.com">Weather</a></li></ul></li><li><a href="http://www.yahoo.com" title="Yahoo! site">Yahoo!</a><ul><li><a href="http://www.yahoo.com/r/26">Sports</a></li><li><a href="http:// www.yahoo.com/r/4c">Tech</a></li></ul></li></ul> <ul id="myMenubar"><li><a title="Google sites" href="http:// www.google.com">Google</a><ul><li><a href="http:// www.gmail.com">GMail</a><ul><li><a href="http://www.gmail.com">Inbox</ a></li><li><a href="http://www.gmail.com">Outbox</a></li></ul></ li><li><a href="http://www.googlecode.com">Google Code</a><ul><li><a href="http://code.google.com/apis/ajaxsearch/">Google Ajax Search</a></ li><li><a href="http://www.google.com/apis/maps/">Google Maps</a></ li><li><a href="http://code.google.com/webtoolkit/">Google Web Toolkit</a></li></ul></li><li><a href="http://www.google.com/ talk">GTalk</a></li></ul></li><li><a href="http://www.msn.com" title="MSN sites">MSN</a><ul><li><a href="http://www.msnbc.com">News</ a></li><li><a href="http://msn.foxsports.com">Sports</a></li><li><a href="http://weather.msn.com">Weather</a></li></ul></li><li><a href="http://www.yahoo.com" title="Yahoo! site">Yahoo!</a><ul><li><a href="http://www.yahoo.com/r/26">Sports</a></li><li><a href="http:// www.yahoo.com/r/4c">Tech</a></li></ul></li></ul> <input type="button" id="testPopupMenu" value="Popup menu" disabled> <ul id="myPopupMenu"><li><a title="Google sites" href="http:// www.google.com">Google</a><ul><li><a href="http:// www.gmail.com">GMail</a><ul><li><a href="http://www.gmail.com">Inbox</ a></li><li><a href="http://www.gmail.com">Outbox</a></li></ul></ li><li><a href="http://www.googlecode.com">Google Code</a><ul><li><a href="http://code.google.com/apis/ajaxsearch/">Google Ajax Search</a></ li><li><a href="http://www.google.com/apis/maps/">Google Maps</a></ li><li><a href="http://code.google.com/webtoolkit/">Google Web Toolkit</a></li></ul></li><li><a href="http://www.google.com/ talk">GTalk</a></li></ul></li><li><a href="http://www.msn.com" title="MSN sites">MSN</a><ul><li><a href="http://www.msnbc.com">News</ a></li><li><a href="http://msn.foxsports.com">Sports</a></li><li><a href="http://weather.msn.com">Weather</a></li></ul></li><li><a href="http://www.yahoo.com" title="Yahoo! site">Yahoo!</a><ul><li><a href="http://www.yahoo.com/r/26">Sports</a></li><li><a href="http:// www.yahoo.com/r/4c">Tech</a></li></ul></li></ul> </body> </html>
David Mark - 30 Sep 2007 01:22 GMT Oops. The instantiation should look more like this:
var displayCheck; el = doc.getElementById('myMenubar'); if (el) { el.style.visibility = 'visible'; displayCheck = el.style && typeof(el.style.display) == 'string' && typeof(el.style.position) == 'string'; if (el.parentNode && displayCheck) { initializeMenu(el); } } el = doc.getElementById('myMenubarVertical'); if (el && el.style) { el.style.visibility = 'visible'; } if (el && el.parentNode && displayCheck) { initializeMenu(el, null, 'right'); } el = doc.getElementById('myPopupMenu'); elButton = doc.getElementById('testPopupMenu'); if (el && el.style) { el.style.visibility = 'visible'; } if (elButton && elButton.style) { elButton.style.visibility = 'visible'; } if (el && el.parentNode && displayCheck) { initializeMenuPopup(el); if (elButton) { elButton.disabled = false; attachPopupActivator(elButton, el); } }
I tangled up the visibility/display/positioning detection. Also, the two references to document.onclick should technically be doc.onclick.
David Mark - 30 Sep 2007 02:33 GMT [snip]
One last thought. It would be nice to allow keyboard users to quickly close the menus without tabbing back to the root (or the activator for a popup.)
Add one the first function and modify the other two.
function attachDocumentKeyHandler(list, root) { if (typeof(root) == 'undefined') { root = list; } var onkeypressOld = doc.onkeypress; var onkeypressNew = function(e) { e = e || global.event; var key = e.which || e.keyCode; if (key == 27 && activeMenu && (isAncestor(activeMenu, list) || activeMenu == list)) { hideActiveMenu(null, root) } }; doc.onkeypress = (onkeypressOld)?function(e) { onkeypressOld(e); onkeypressNew(e); }:onkeypressNew; }
function initializeMenu(list, className, initialSide) { list.className = className || 'menubar'; list.style.position = 'relative'; initializeChildMenus(list, list, initialSide); attachDocumentClickHandler(list); attachDocumentKeyHandler(list); }
function initializeMenuPopup(list, className) { list.className = className || 'menuPopup'; list._isRootless = true; initializeChildMenus(list, null); list.style.position = 'absolute'; list.style.display = 'none'; attachDocumentClickHandler(list, null); attachDocumentKeyHandler(list, null); }
David Mark - 30 Sep 2007 06:24 GMT [snip]
Took a moment to try this in IE6 and it looked a lot like IE7 quirks mode. That was surprising as there isn't usually a correlation between IE6 standards and IE7 quirks. I had forgotten how unpredictable lists were in IE.
In short, IE6 requires widths for the list items (which sucks.) I gave them all the same widths and tweaked a few other things with conditional comments. The result is a lot uglier, but at least there are no parse-related hacks. The rendering is the same as before in everything but IE6. Other than the fixed widths, IE6 looks the same as everything else. Quirks mode is definitely out, but not necessarily IE5.5 as there are no box model issues. I suspect Mac IE will have some some problems, but couldn't care less at this point.
Also note that one of the menus in the original is too wide for 6em. I didn't bother to add a specific rule to accommodate it, so that menu will look weird in IE6 unless the captions are shortened.
<style type="text/css" media="all"> ul.menubar { list-style-type:none;padding:0;margin:0 } ul.menubar a, ul.menuPopup a { padding: 0 .25em 0 .25em } ul.menubar li { margin:0;padding:0;display:inline}
ul.menubar li a:link, ul.menubar li a:visited { text-decoration:none } ul.menubar li a:hover { background-color:#0000DD;color:white } ul.menuPopup { list-style-type:none;padding:0;margin:0;border:outset 2px;background-color:threedface;color:windowtext;z-index:1 } ul.menuPopup li { white-space:nowrap;display:block;width:auto } ul.menuPopup li a { width:auto } ul.menuPopup li a:link, ul.menuPopup li a:visited { text- decoration:none } ul.menuPopup li a:hover { background-color:#0000DD;color:white } ul.menuPopup li a.popup:after { content: "\0020\00BB"; }
#myMenubarVertical.menubar { width:6em;margin-bottom:1em } #myMenubarVertical.menubar li { display:block;width:auto } #myMenubarVertical.menubar li a { width:auto }
#testPopupMenu { display:block; margin-top:1em }
body {font-family:sans-serif;background-color:threedface} </style> <!--[if !IE]>--> <style type="text/css" media="all"> #myMenubarVertical.menubar li a, ul.menuPopup li a { display:block } </style> <!--<![endif]--> <!--[if IE]> <style type="text/css" media="all"> ul.menubar { display:inline-block } /* Adds layout to fix IE relative positioning bug */ </style> <![endif]--> <!--[if gt IE 6]> <style type="text/css" media="all"> #myMenubarVertical.menubar li a, ul.menuPopup li a { display:block } </style> <![endif]--> <!--[if lt IE 7]> <style type="text/css" media="all"> ul.menubar li, ul.menubar li a, ul.menuPopup li, ul.menuPopup li a { height:1% } ul.menuPopup li, ul.menuPopup li a, #myMenubarVertical.menubar li, #myMenubarVertical.menubar li a { width:6em; zoom:1 } </style> <![endif]-->
Thomas 'PointedEars' Lahn - 28 Sep 2007 20:48 GMT > I would appreciate recommendations for JavaScript code that implements > drop-down, hierarchical menus. Are there high quality libraries for > this, or is it more typical for people to roll their own? Let JScript(!) code add to the functionality of CSS where required. Don't attempt to replace HTML and the latter by a client-side script that generates the content; the result would be inevitably inaccessible.
PointedEars
 Signature "Use any version of Microsoft Frontpage to create your site. (This won't prevent people from viewing your source, but no one will want to steal it.)" -- from <http://www.vortex-webdesign.com/help/hidesource.htm>
Brian Adkins - 29 Sep 2007 17:51 GMT Here are a few I've found. Any good/bad experiences with any of them?
Yahoo! UI Library: Menu http://developer.yahoo.com/yui/menu/
Son of Suckerfish - Nice, but menu collapses unforgivingly http://www.htmldog.com/articles/suckerfish/dropdowns/
FreeStyle Menu - Angus Turnbull http://www.twinhelix.com/dhtml/fsmenu/demo/
jdMenu plugin for JQuery http://jdsharp.us/jQuery/plugins/jdMenu/
I also forgot to list one requirement. I'm using XHTML 1.0 Strict, so the menu would need to be compatible with that.
At this point, I'm leaning toward starting with Son of Suckerfish and adding JavaScript to make the collapsing more forgiving. It seems like the simplest and I like the idea of building something onto a simple foundation versus trying to understand someone else's monstrosity.
I would be curious about experiences with Yahoo's menu or other libraries with significant developer acceptance.
Randy Webb - 29 Sep 2007 21:07 GMT Brian Adkins said the following on 9/29/2007 12:51 PM:
<snip>
> I also forgot to list one requirement. I'm using XHTML 1.0 Strict, so > the menu would need to be compatible with that. Why are you using something that isn't understood by 90% of the web and would end up being processed as soup tag HTML and thus a true XHTML script wouldn't work with it?
 Signature Randy Chance Favors The Prepared Mind comp.lang.javascript FAQ - http://jibbering.com/faq/index.html Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
Brian Adkins - 29 Sep 2007 21:34 GMT > Brian Adkins said the following on 9/29/2007 12:51 PM: > > I also forgot to list one requirement. I'm using XHTML 1.0 Strict, so [quoted text clipped - 3 lines] > would end up being processed as soup tag HTML and thus a true XHTML > script wouldn't work with it? I wasn't aware that "90% of the web" doesn't understand it. Can you provide documentation for that statistic? I have to admit being skeptical since my testing has uncovered no issues and there are a number of major sites using the same doctype, but I'd like to keep an open mind.
I'm not familiar with the phrase "soup tag HTML", but it doesn't sound good. Which browsers process XHTML as "soup tag HTML" ? I also don't know what you mean by a "true XHTML script" - is this different than a regular old JavaScript script? Are you saying that many browsers will populate the DOM differently from XHTML input than from HTML? If you can provide examples of input that validates against XHTML 1.0 Strict that turns into "soup tag HTML" and thus won't work with a valid JavaScript program I would appreciate it.
Just out of curiosity, which doctype do you prefer?
Brian Adkins - 29 Sep 2007 21:47 GMT > > Brian Adkins said the following on 9/29/2007 12:51 PM: > > > I also forgot to list one requirement. I'm using XHTML 1.0 Strict, so [quoted text clipped - 20 lines] > > Just out of curiosity, which doctype do you prefer? Just in case we're talking about two different things, here's the doctype & other stuff I'm using:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> <head> ... <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> ...
Thomas 'PointedEars' Lahn - 29 Sep 2007 22:12 GMT >>> Brian Adkins said the following on 9/29/2007 12:51 PM: >> [...] >> I'm not familiar with the phrase "soup tag HTML", but it doesn't sound >> good. Which browsers process XHTML as "soup tag HTML" ? The correct term is "tag soup HTML" which is the way most (if not all) parsers in browsers work. If they do no support a HTML feature or encounter not Valid code, they do error correction. That is a behavior not allowed for XML documents such as XHTML documents; they have to be well-formed (they need not to be Valid, although due to the definition of validating parsers that is strongly recommended).
http://www.hixie.ch/advocacy/xhtml http://hsivonen.iki.fi/xhtml-the-point/
>> I also don't know what you mean by a "true XHTML script" - is this >> different than a regular old JavaScript script? Did you even know that there is no such thing as a "regular old JavaScript script" as every different UA uses a different script engine and DOM?
>> Are you saying that many browsers will populate the DOM differently from >> XHTML input than from HTML? Yes, they do. Although that is not supported by Web standards. For example, document.write() doesn't work (i.e. throws an exception) in the XHTML Gecko DOM with the excuse of its being capable of creating not well-formed markup.
http://www.w3.org/TR/DOM-Level-2-HTML/
>> If you can provide examples of input that validates against XHTML 1.0 Strict >> that turns into "soup tag HTML" and thus won't work with a valid >> JavaScript program I would appreciate it. YMMD.
>> Just out of curiosity, which doctype do you prefer? HTML 4.01 Strict, unless XHTML is absolutely required. If the latter, XHTML 1.0 Strict or XHTML 1.1.
> Just in case we're talking about two different things, here's the > doctype & other stuff I'm using: [quoted text clipped - 6 lines] > <meta http-equiv="Content-Type" content="text/html; > charset=utf-8" /> This is strongly recommended against if you serve it as text/html:
http://www.w3.org/TR/xhtml-media-types/#summary
And, in fact, if the XHTML was parsed by an XML parser as it should be, that declaration would be far too late. An XML document has to be well-formed *before* parsing starts. That is facilitated by declaring the encoding in the HTTP header or in an XML processing instruction before the root element of the document (PI):
<?xml version="1.0" encoding="ISO-8859-1"?>
As for scripting, there are more things to care about when using XHTML.
http://www.w3.org/TR/xhtml1/#diffs
PointedEars
 Signature "Use any version of Microsoft Frontpage to create your site. (This won't prevent people from viewing your source, but no one will want to steal it.)" -- from <http://www.vortex-webdesign.com/help/hidesource.htm>
Brian Adkins - 29 Sep 2007 23:25 GMT On Sep 29, 5:12 pm, Thomas 'PointedEars' Lahn <PointedE...@web.de> wrote:
> >>> Brian Adkins said the following on 9/29/2007 12:51 PM: > >> [...] [quoted text clipped - 9 lines] > > http://www.hixie.ch/advocacy/xhtml Interesting information. I do validate my pages, and I'm not planning on sending as 'application/xhtml+xml' anytime soon, but it certainly may be that I assumed there were advantages to XHMTL 1.0 Strict after reading various information sources (i.e. jumped on a bandwagon). Some of the proposed benefits of XHTML I've heard are:
* future proofing web pages * allowing aural screen readers to more easily consume it * it's becoming the language of choice for mobile devices * existing data is more easily transformed into XHTML than HTML * there's not going to be an HTML 5, the new standard is XHTML 1.0 * <br> seems wrong compared to <br /> * etc.
For what it's worth, here are the doctypes of 49 sites that I checked in mid July:
http://lojic.com/blog/2007/07/12/which-doctypes-are-being-used/
Summary is: none = 10, html = 20, xhtml = 19 (only 1 using XHTML 1.1)
You've given me some things to think about. If anyone is aware of advantages of XHTML 1.1 Strict over HTML 4.01 Strict, feel free to chime in.
> >> Just out of curiosity, which doctype do you prefer? > > HTML 4.01 Strict, unless XHTML is absolutely required. If the latter, XHTML > 1.0 Strict or XHTML 1.1. Thomas 'PointedEars' Lahn - 29 Sep 2007 23:52 GMT >>>>> Brian Adkins said the following on 9/29/2007 12:51 PM: >>>> [...] [quoted text clipped - 11 lines] > Interesting information. I do validate my pages, and I'm not planning > on sending as 'application/xhtml+xml' anytime soon, Why not if the UA supports it? Gecko-based UAs do, and they use an XML parser then.
> but it certainly may be that I assumed there were advantages to XHMTL 1.0 Strict > after reading various information sources (i.e. jumped on a bandwagon). Some > of the proposed benefits of XHTML I've heard are: > > * future proofing web pages HTML support is not going to disappear. Whether or not XHTML will evolve into a viable alternative for HTML remains to be seen.
> * allowing aural screen readers to more easily consume it NAK. Please explain why you think that would be so.
> * it's becoming the language of choice for mobile devices Because of the short-lived WAP hype using WML?
> * existing data is more easily transformed into XHTML than HTML Again, an explanation would be appreciated.
> * there's not going to be an HTML 5, the new standard is XHTML 1.0 The WHATWG is developing its HTML 5 now. While I debate that proprietary approach, it remains to be seen whether or not it will be used more than XHTML 1.0.
http://www.whatwg.org/specs/web-apps/current-work/
> * <br> seems wrong compared to <br /> On what grounds?
> * etc. > [quoted text clipped - 4 lines] > > Summary is: none = 10, html = 20, xhtml = 19 (only 1 using XHTML 1.1) And probably most of the sites that use XHTML them serve it inefficient and error-prone as text/html without a real need for XHTML in the first place. Yuck.
> You've given me some things to think about. If anyone is aware of > advantages of XHTML 1.1 Strict over HTML 4.01 Strict, feel free to > chime in. But please do that only where it is on-topic.
F'up2 comp.infosystems.www.authoring.html
PointedEars
 Signature realism: HTML 4.01 Strict evangelism: XHTML 1.0 Strict madness: XHTML 1.1 as application/xhtml+xml -- Bjoern Hoehrmann
Brian Adkins - 30 Sep 2007 00:44 GMT On Sep 29, 6:52 pm, Thomas 'PointedEars' Lahn <PointedE...@web.de> wrote:
> But please do that only where it is on-topic. That is appropriate, but I find it humorous nonetheless considering very little of this thread has been on topic. Who knows, maybe someone will show up with some useful info regarding JavaScript menus after all.
Randy Webb - 30 Sep 2007 03:26 GMT Thomas 'PointedEars' Lahn said the following on 9/29/2007 6:52 PM:
<snip>
>> You've given me some things to think about. If anyone is aware of >> advantages of XHTML 1.1 Strict over HTML 4.01 Strict, feel free to >> chime in. > > But please do that only where it is on-topic. Agreed. As the advantages/disadvantages of XHTML versus HTML, and the ability to script the two different DOM'es with one script would be totally off-topic to clj
> F'up2 comp.infosystems.www.authoring.html F'up set back where I want it set for my post.
 Signature Randy Chance Favors The Prepared Mind comp.lang.javascript FAQ - http://jibbering.com/faq/index.html Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
David Mark - 30 Sep 2007 00:52 GMT > On Sep 29, 5:12 pm, Thomas 'PointedEars' Lahn <PointedE...@web.de> > wrote: [quoted text clipped - 15 lines] > Interesting information. I do validate my pages, and I'm not planning > on sending as 'application/xhtml+xml' anytime soon, but it certainly Then why are you writing XHTML?
> may be that I assumed there were advantages to XHMTL 1.0 Strict after > reading various information sources (i.e. jumped on a bandwagon). Some Yep.
> of the proposed benefits of XHTML I've heard are: > > * future proofing web pages Somewhat true, though many will argue that HTML5 is the real future. But if you are going to serve your pages as HTML, you should write them as HTML.
> * allowing aural screen readers to more easily consume it Hardly. Most screen readers rely on browsers to parse your tag soup, so there is no benefit there. Moreover, I know of no aural browsers with XML parsers.
> * it's becoming the language of choice for mobile devices Not really. I imagine you are thinking of XHTML Basic, but that has little to do with serving XHTML 1.0 as HTML.
> * existing data is more easily transformed into XHTML than HTML Backwards. It is easier to retrieve data from XHTML.
> * there's not going to be an HTML 5, the new standard is XHTML 1.0 XHTML 1.0 is an old standard and it doesn't look like HTML 5 is going away. Regardless, the two are not mutually exclusive.
> * <br> seems wrong compared to <br /> It is wrong for XHTML, but correct for HTML.
> * etc. > [quoted text clipped - 4 lines] > > Summary is: none = 10, html = 20, xhtml = 19 (only 1 using XHTML 1.1) That one person using XHTML 1.1 is nuts and I suspect the 19 using XHTML are doing what you are doing (serving tag soup HTML.)
> You've given me some things to think about. If anyone is aware of > advantages of XHTML 1.1 Strict over HTML 4.01 Strict, feel free to > chime in. Zero advantages and lots of pitfalls. XHTML 1.1 is not appropriate for public Web sites.
Thomas 'PointedEars' Lahn - 29 Sep 2007 21:52 GMT >> Brian Adkins said the following on 9/29/2007 12:51 PM: >>> I also forgot to list one requirement. I'm using XHTML 1.0 Strict, so [quoted text clipped - 5 lines] > I wasn't aware that "90% of the web" doesn't understand it. Can you > provide documentation for that statistic? He is referring to Microsoft Internet Explorer not using a built-in XML parser for XHTML by default, and not supporting the proper media type for XHTML, application/xhtml+xml, to date (version 7.0). Whether or not it still has a 90% market share or not (142% of all Web statistics are flawed) is irrelevant; it is a sad fact that its flawed layout engine (Trident) is still the most used one, and that the advantages XHTML undoubtedly has over HTML must still be carefully weighted against the disadvantage of the former's being not widely supported.
http://en.wikipedia.org/wiki/Internet_Explorer http://en.wikipedia.org/wiki/Internet_Explorer#Standards_support
PointedEars
Brian Adkins - 29 Sep 2007 22:19 GMT On Sep 29, 4:52 pm, Thomas 'PointedEars' Lahn <PointedE...@web.de> wrote:
> >> Brian Adkins said the following on 9/29/2007 12:51 PM: > >>> I also forgot to list one requirement. I'm using XHTML 1.0 Strict, so [quoted text clipped - 9 lines] > parser for XHTML by default, and not supporting the proper media type for > XHTML, application/xhtml+xml, ... I see. I'm not serving it as 'application/xhtml+xml', and haven't had any issues with IE so far. I guess the 'text/html' vs. 'application/ xhtml+xml' accounts for the discrepancy between "90% of the web doesn't understand it" and what I'm seeing.
Thomas 'PointedEars' Lahn - 29 Sep 2007 22:51 GMT >>>> Brian Adkins said the following on 9/29/2007 12:51 PM: >>>>> I also forgot to list one requirement. I'm using XHTML 1.0 Strict, so [quoted text clipped - 9 lines] > > I see. I'm not serving it as 'application/xhtml+xml', But as what?
> and haven't had any issues with IE so far. I guess the 'text/html' vs. > 'application/xhtml+xml' accounts for the discrepancy between "90% of > the web doesn't understand it" and what I'm seeing. It merely accounts for the possibility of your not understanding what you are doing, see <46FEBFAE.4010209@PointedEars.de>.
PointedEars
 Signature Prototype.js was written by people who don't know javascript for people who don't know javascript. People who don't know javascript are not the best source of advice on designing systems that use javascript. -- Richard Cornford, cljs, <f806at$ail$1$8300dec7@news.demon.co.uk>
Brian Adkins - 29 Sep 2007 23:44 GMT On Sep 29, 5:51 pm, Thomas 'PointedEars' Lahn <PointedE...@web.de> wrote:
> >>>> Brian Adkins said the following on 9/29/2007 12:51 PM: > >>>>> I also forgot to list one requirement. I'm using XHTML 1.0 Strict, so [quoted text clipped - 18 lines] > It merely accounts for the possibility of your not understanding > what you are doing, see <46FEBFAE.4010...@PointedEars.de>. You could be right. I should probably hear your perspective on the discrepancy between someone's statement that XHTML 1.0 Strict won't work on "90% of the web", and the fact that I haven't uncovered any problems (except for losing the target attribute on <a>) on 5 browsers running on 3 operating systems covering well over 90% market share.
I've heard someone say that the difference between theory and practice is much greater in practice than in theory ;)
Randy Webb - 30 Sep 2007 02:35 GMT Brian Adkins said the following on 9/29/2007 6:44 PM:
> On Sep 29, 5:51 pm, Thomas 'PointedEars' Lahn <PointedE...@web.de> > wrote: [quoted text clipped - 23 lines] > problems (except for losing the target attribute on <a>) on 5 browsers > running on 3 operating systems covering well over 90% market share. If you don't serve it as XHTML then it isn't XHTML. And no DTD (or any other element/tag/code in the page) will make the browser interpret it as XHTML. Even your Firefox is interpreting it as HTML. Serve it with a proper MIME type and see what IE does with it.
 Signature Randy Chance Favors The Prepared Mind comp.lang.javascript FAQ - http://jibbering.com/faq/index.html Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
Peter Michaux - 30 Sep 2007 03:12 GMT > Brian Adkins said the following on 9/29/2007 6:44 PM: > [quoted text clipped - 30 lines] > as XHTML. Even your Firefox is interpreting it as HTML. Serve it with a > proper MIME type and see what IE does with it. I'd think these quotations would be justification enough.
http://www.webdevout.net/articles/beware-of-xhtml#quotes
Peter
Brian Adkins - 30 Sep 2007 04:40 GMT > > Brian Adkins said the following on 9/29/2007 6:44 PM: > [quoted text clipped - 36 lines] > > Peter Yes, I find those quotes signficant.
I see what Randy was trying to say in his initial post - the subtlety was lost on me. I was ignorant of the fact that my carefully crafted XHTML 1.0 Strict code was being handled as as HTML. I think I figured the 'text/html' content type was simply to placate IE and that the XHTML capable browsers would obey the doctype. From my research today, it's clear that this is an all too common misconception. Bad book authors :)
This is certainly a heavily debated topic, but I've personally been unable to find enough evidence to justify serving XHTML up as HTML, so unless I turn up something significant in the next few days, I think I'll switch to HTML 4.01 Strict and continue to code in an XHTML style. At least I feel better informed now.
There certainly seems to be a strong trend in moving to XHTML with a 'text/html' content type, so it appears that either a lot of major site operators are misinformed, or I've yet to get all the relevant facts about this.
Peter Michaux - 30 Sep 2007 05:14 GMT > I think > I'll switch to HTML 4.01 Strict and continue to code in an XHTML > style. If you use HTML doctype it would be wise to make sure your markup is valid HTML (just forget about XHTML all together).
http://validator.w3.org/
Peter
Randy Webb - 30 Sep 2007 06:10 GMT Brian Adkins said the following on 9/29/2007 11:40 PM:
<snip>
>> I'd think these quotations would be justification enough. >> [quoted text clipped - 11 lines] > it's clear that this is an all too common misconception. Bad book > authors :) Yes. Most programming books are not worth the paper they are printed on.
> This is certainly a heavily debated topic, but I've personally been > unable to find enough evidence to justify serving XHTML up as HTML, so > unless I turn up something significant in the next few days, I think > I'll switch to HTML 4.01 Strict and continue to code in an XHTML > style. At least I feel better informed now. You can save yourself a "few days" of searching and simply forget about XHTML for anytime in the foreseeable future. Just don't forget that HTML doesn't have a short tag syntax.
> There certainly seems to be a strong trend in moving to XHTML with a > 'text/html' content type, so it appears that either a lot of major > site operators are misinformed, or I've yet to get all the relevant > facts about this. They are either misinformed, ignorant, or just want to be able to say "We use XHTML on our AJAX site" or something similar. First bet is on ignorance though.
 Signature Randy Chance Favors The Prepared Mind comp.lang.javascript FAQ - http://jibbering.com/faq/index.html Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
Richard Cornford - 30 Sep 2007 19:31 GMT <snip>
>>> If you don't serve it as XHTML then it isn't XHTML. And no >>> DTD (or any other element/tag/code in the page) will make [quoted text clipped - 14 lines] > simply to placate IE and that the XHTML capable browsers would > obey the doctype. Which means that you were also not aware that there is a distinction between HTML DOMs and XHTML DOMs. If you are scripting a DOM absolutely the last thing you would want is to be scripting one type of DOM in one browser and another type in the next.
> From my research today, it's clear that this is an all too > common misconception. All too common, and such that sufferers from the misconception are extremely resistant to being corrected.
> Bad book authors :) Yes, but not only. Bad web page authors (directly, and those writing pages on writing web pages) are probably more guilty (by weight of numbers) , along with the participants in small circulation web forums, mailing lists and other web development 'communities'.
> This is certainly a heavily debated topic, but I've personally > been unable to find enough evidence to justify serving XHTML > up as HTML, so unless I turn up something significant in the > next few days, I think I'll switch to HTML 4.01 Strict and > continue to code in an XHTML style. At least I feel better > informed now. While you are judging the 'significance' of what you find consider the consequence of scripting such a document. Since almost no non-trivial scripts will operate successfully with both and HTML DOM and an XHTML DOM and a document served as text/html will result in the browser exposing an HTML DOM to be scripted, will it ever make sense to be marking-up a document as XHTML and then scripting with the pre-requisite that it will _never_ be interpreted as being an XHTML document by a web browser.
> There certainly seems to be a strong trend in moving to XHTML > with a 'text/html' content type, There certainly is a strong trend towards seeing increasing quantities of XHTML-style mark-up in documents (whether they be XHTML or not). It is most obvious that fundamental miscomputations are driving this trend when you observe the number of documents where <br> appears alongside <br /> (or when you see things like <BR />).
> so it appears that either a lot of major site operators are > misinformed, or I've yet to get all the relevant facts about > this. The general standard of technical understanding, even on 'major sites', is so low that 'misinformed' is probably pushing things too far. To be misinformed you need to be (in some sense) 'informed' in the first place. Plain old endemic ignorance is a much better explanation; these people just don't know why they are doing what they are doing.
Much of the time when we get into this XHTML/HTML discussion here it quickly obvious that the individuals being asked why they are using XHTML-style mark-up while scripting an HTML DOM not only don't know that there is a distinction between the types of DOM, but don't actually know what an HTTP content-type header is. These is no informed decision making in what they do, just the random outcome of the aggregation of an extended sequence of 'learnt' mystical incantations.
The depth, and pervasive nature of, that endemic ignorance is best illustrated by the current set of 'popular' javascript libraries. Where people who don't know any better are importing the ignorance of others into their own projects.
On Monday morning I have been asked to analyse why an 'AJAX' web application written by one of our subsidiary companies runs so badly on IE6 as to be non-viable. I have not seen the code yet and the only things I know about it are that it was written by experienced Java programmers (so I am expecting them to have made all the mistakes I made when moving from Java to javascript) and that they have used to 'popular' dojo library. In preparation I thought it would be a good idea to have a look at the dojo library code, so I spent a few hours yesterday doing that, to discover (as I expected I would) that its authors were not particularly knowledgeable about javascript or browser scripting. To illustrate:-
From a file called "dojo.js" (re-wrapped for newsgroup posting):-
| document.write("<scr"+"ipt type='text/javascript' src='"+ | spath+ | "'></scr"+"ipt>" | ); In the mark-up string being presented to the - document.write - method you will see two string concatenation operations being used to 'split-up' the SCRIPT opening and closing tags. This is a mystical incantation that ignorant script authors chant in the face of a real issue. The real issues is that when an HTML parser encounters an opening SCRIPT tag it must determine how much (if any) of the following material is script code that should be sent to a script engine for processing and when it should resume processing the input stream as HTML mark-up. The obvious signal for the end of contents of a SCRIPT element would be the closing SCRIPT tag. However, the HTML parser has no means of seeing the characters in the input stream as anything other than characters so if a javascript string contains the character sequence '</script>' the HTML parser is going to see that as the character sequence it is interested in; the end of the contents of the SCRIPT element. Resulting in an unterminated string literal error in the javascript source and gibberish text content in the HTML document.
There is also a formal issue that differs slightly form the real issue. The HTML specification clearly states that CDATA contents of an element (SCRIPT element contents are CDATA in HTML) may be terminated by the first occurrence of the character sequence '</'. In practice no browsers are known to follow this aspect of the HTML specification to the letter, but a knowledgeable HTML author would have no excuse for complaint if a future browser did terminate CDATA sections at the point of first encountering the character sequence '</'.
So the things that make the above code a mystical incantation are:-
1. The string concatenation operation in the opening SCRIPT tag is a needless runtime overhead to do something that has no relationship to either the real issue or the formal issue. It just should never have appeared in any code. 2. The string concatenation operation in the closing SCRIPT element may deal with the real issue but it does not address the formal issue. While any approach that did address the formal issue by breaking up the '</' sequence would also break up the '</script> sequence. 3. A concatenation operation is a poor approach to this issue as the HTML parser is only able to see the raw source text characters. Breaking up the problematic character sequences with escape (backslash) characters would be just as effective at concealing them form the HTML parser but would do so in a way that had no consequences beyond the point where the string literal was converted into a string primitive value (during the compiling of the script into an executable). That is, there is no need for the runtime overhead of two (or four in this case) string concatenation operations. The recommended approach is to turn the sequence '</script>' in string literals into the sequence '<\/script>' and so address the real and formal issues without any runtime overhead. 4. The code is actually in an external javascript resource and so will never be presented to an HTML parser for examination. Neither the real nor the formal issues apply to this code at all.
Another illustration is to be found in dojo's 'dom.js:-
| if( | elem == null || | ((elem == undefined)&&(typeof elem == "undefined")) | ){ | dojo.raise("No element given to dojo.dom.setAttributeNS"); | } Using the type-converting equality operator (- == -) there are precisely two values that are equal to null. They are null (unsurprisingly) and the undefined value. In the above tests whenever - elem - is null or undefined the - elem == null - expression is true and the - ((elem == undefined)&&(typeof elem == "undefined")) - expression is not evaluated. So whenever the - ((elem == undefined)&&(typeof elem == "undefined")) - expression is evaluated the value of - elem - must be neither null nor undefined. But if - elem - must be neither null nor undefined then - (elem == undefined) - must always be false (as only undefined and null equal (by type-converting equality) undefined), and as - (elem == undefined) - must be false the - (typeof elem == "undefined") - can *never* be evaluated.
We are looking at code where the author has written the test expression - elem == null - without understanding the operation being performed and made that ignorance self-evident by following it with a test that can only have one outcome in its context, and a third test that can never be evaluated (though if it were evaluated the result would be as predictably false as the - (elem == undefined) - expression).
The annoying part of this nonsense is that in its normal use, when - elem - will be a reference to a DOM Element, that - (elem == undefined) - is going to be evaluated, and it is going to produce its predictably false result. Just another avoidable runtime overhead, included for no reason other than ignorance.
It is unlikely that dojo is the work of a single individual, but we can be certain that of everyone involved the individual with the greatest knowledge of the subject does not know javascript well enough to understand how the code written is going to behave (or enough to distinguish between chanting mystical incarnations and browser scripting). However, you find that the authors of these 'popular' libraries acquire a strange status in the eyes of (presumably even more ignorant) others, get invited to speak at conferences, feel themselves qualified to instruct others on how they should be writing javascript, and so on.
So yes we do live in a world where the operators of 'major sites' are misinformed, and likely to stay that way because the odds are that the next person to 'inform' them will likely be as misinformed themselves.
Richard.
Peter Michaux - 30 Sep 2007 20:34 GMT On Sep 30, 11:31 am, "Richard Cornford" <Rich...@litotes.demon.co.uk> wrote:
[snip examples of less than optimal code in dojo]
> So yes we do live in a world where the operators of 'major sites' are > misinformed, and likely to stay that way because the odds are that the > next person to 'inform' them will likely be as misinformed themselves. Would you agree that most niches in the programming world are filled with people that are misinformed and making decision that are randomly good or bad? I would say mediocrity and satifaction with just enough information to avoid being fired extends to some fraction of individuals in every intellectual field with which I have had contact.
N.B. I'm not claiming I'm anything other than average. I have no justification to do so.
Peter
Richard Cornford - 30 Sep 2007 21:52 GMT > [snip examples of less than optimal code in dojo] "Less then optimal"? That code was well into the range of b***dy stupid.
>> So yes we do live in a world where the operators of 'major >> sites' are misinformed, and likely to stay that way because [quoted text clipped - 4 lines] > filled with people that are misinformed and making decision > that are randomly good or bad? Not in my experience.
> I would say mediocrity and satifaction with just enough > information to avoid being fired extends to some fraction of > individuals in every intellectual field with which I have > had contact. <snip>
There is a big difference between "most" and "some".
But what is your point? Does an inept programmer become competent when the person sitting at the next desk is worse?
Richard.
Brian Adkins - 01 Oct 2007 17:07 GMT On Sep 30, 2:31 pm, "Richard Cornford" <Rich...@litotes.demon.co.uk> wrote:
> > I think I figured the 'text/html' content type was > > simply to placate IE and that the XHTML capable browsers would > > obey the doctype. > > Which means that you were also not aware that there is a distinction > between HTML DOMs and XHTML DOMs. Correct.
> > I think I'll switch to HTML 4.01 Strict and > > continue to code in an XHTML style. At least I feel better > > informed now. > > While you are judging the 'significance' of what you find consider the > consequence of scripting such a document. Just to clarify. What I meant by 'coding in an XHTML style' is things like using lowercase attribute names with quotations, using closing tags even if they're optional, etc. such that the markup is valid HTML resulting in an HTML DOM.
> The depth, and pervasive nature of, that endemic ignorance is best > illustrated by the current set of 'popular' javascript libraries. Where > people who don't know any better are importing the ignorance of others > into their own projects. Could it be that people are simply doing their best to try and find a library that is the lesser of evils to avoid the disadvantages of writing everything themselves? In my short time on c.l.j, I have seen many criticisms of JavaScript libraries but few recommendations. It could be that they simply got lost in the noise.
Are there any JavaScript libraries that you can recommend over reinventing wheels? I checked the FAQ and didn't see anything.
I'm also curious if the folks criticizing the 'popular' JavaScript libraries (or their authors) have attempted to improve the code - either by direct contribution or via educating the authors. Or are they beyond hope?
Thomas 'PointedEars' Lahn - 01 Oct 2007 17:20 GMT > On Sep 30, 2:31 pm, "Richard Cornford" <Rich...@litotes.demon.co.uk> > wrote: [quoted text clipped - 8 lines] > tags even if they're optional, etc. such that the markup is valid HTML > resulting in an HTML DOM. If you observe more closely, you will see that XHTML cannot be made fully HTML-compatible this way, at least because IE renders <br></br> as *two* lines. And XHTML 1.0, Appendix C (which is not normative BTW), fails to recognize that in a non-tagsoup HTML parser `<br />' equals `<br>>'.
PointedEars
 Signature var bugRiddenCrashPronePieceOfJunk = ( navigator.userAgent.indexOf('MSIE 5') != -1 && navigator.userAgent.indexOf('Mac') != -1 ) // Plone, register_function.js:16
Brian Adkins - 01 Oct 2007 18:25 GMT On Oct 1, 12:20 pm, Thomas 'PointedEars' Lahn <PointedE...@web.de> wrote:
> > Just to clarify. What I meant by 'coding in an XHTML style' is things > > like using lowercase attribute names with quotations, using closing [quoted text clipped - 5 lines] > lines. And XHTML 1.0, Appendix C (which is not normative BTW), fails to > recognize that in a non-tagsoup HTML parser `<br />' equals `<br>>'. My goal is *not* to make XHTML fully HTML-compatible. I stated "such that the markup is valid HTML" and referred to "optional" closing tags, not "forbidden" ones, yet you show <br> with an end tag which is forbidden (as it is for <img>, <meta>, etc.) according to the spec here:
http://www.w3.org/TR/html401/index/elements.html
On the other hand, the closing tag for <p> is optional (as is <body>, <li>, etc.), but in keeping with an XHTML "style" I would choose to include the closing tag when optional.
I appreciate your enthusiasm, but maybe you could channel this extra energy into recommending a JavaScript library "that doesn't suck" :)
Peter Michaux - 01 Oct 2007 18:52 GMT > recommending a JavaScript library "that doesn't suck" :) You realize how dangerous it is for someone to make such a recommendation on c.l.j? If the library isn't perfect then it "sucks".
I'll stick my neck out and say I think mine doesn't suck. I need to make a few changes which are mostly stylistic.
<URL: http://forkjavascript.org/>
I've never seen another library tested so widely
<URL: http://forkjavascript.org/welcome/browser_support>
Peter
Thomas 'PointedEars' Lahn - 01 Oct 2007 20:50 GMT >>> Just to clarify. What I meant by 'coding in an XHTML style' is things >>> like using lowercase attribute names with quotations, using closing [quoted text clipped - 6 lines] > > My goal is *not* to make XHTML fully HTML-compatible. But that has to be your goal or you have neither Valid XHTML nor Valid HTML markup that can be used to create a document tree in the DOM.
> I stated "such that the markup is valid HTML" and referred to "optional" > closing tags, not "forbidden" ones, yet you show <br> with an end tag which > is forbidden (as it is for <img>, <meta>, etc.) according to the spec > here: > > http://www.w3.org/TR/html401/index/elements.html Utter nonsense. As you can observe in the specification, all HTML elements with an empty content model, including the `br', `img' and `meta' elements, have an *optional* end tag. That goes for HTML 3.2, HTML 4.01 Transitional, Frameset, and Strict, and (so) even ISO HTML. It is that property of HTML that can make XHTML 1.0 HTML-compatible generally, if it were not for the faulty Trident.
> On the other hand, the closing tag for <p> is optional As is `</br>'.
> [...] > I appreciate your enthusiasm, but maybe you could channel this extra > energy into recommending a JavaScript library "that doesn't suck" :) Since I never had the need for a library for the feature you are looking for (as the posted links should have proven already), I can not recommend one. In fact, any script library that would be required for that (in contrast to a little behavior-.htc) can safely be recommended against on the Web as it will not degrade gracefully and so it will not be interoperable and the outcome will not conform to accessibility guidelines.
PointedEars
 Signature var bugRiddenCrashPronePieceOfJunk = ( navigator.userAgent.indexOf('MSIE 5') != -1 && navigator.userAgent.indexOf('Mac') != -1 ) // Plone, register_function.js:16
Thomas 'PointedEars' Lahn - 01 Oct 2007 21:37 GMT >> I stated "such that the markup is valid HTML" and referred to "optional" >> closing tags, not "forbidden" ones, yet you show <br> with an end tag which [quoted text clipped - 6 lines] > with an empty content model, including the `br', `img' and `meta' elements, > have an *optional* end tag. [...] I can see now how and why you got the impression that the end tags would be forbidden. You will have to ignore that column of this non-normative index where there is an "F" for "Forbidden" (as you will have to ignore many non-normative examples in W3C specifications that propose bad practice). There is exactly nothing in the DTD that forbids to use an/the optional end tag for those elements (or any other element), nor is there anything in the corresponding normative sections of the specification that says so. For example, the declaration for the HTML `br' element in HTML 4.01 Strict is as follows:
| <!ELEMENT BR - O EMPTY -- forced line break --> | <!ATTLIST BR | %coreattrs; -- id, class, style, title -- | > You will observe the `-' after the element type identifier `BR' that means the start tag of the element is _not_ optional. You will also observe the following `O' that means the end tag of the element *is indeed* optional (and not at all forbidden), and the `EMPTY' which says that the content model of the element is empty, i.e. it must not have any content (e.g. `<br>foo</br>' is indeed forbidden).
HTH
PointedEars
 Signature "Use any version of Microsoft Frontpage to create your site. (This won't prevent people from viewing your source, but no one will want to steal it.)" -- from <http://www.vortex-webdesign.com/help/hidesource.htm>
|
|