Tag Archives: DHTML

IE6 doesn’t support onclick handlers for

Instead, you have to use an onchange handler in the SELECT, like this:

<html>
<head>
<script>
function fAlertA() { alert(‘A’); }
function fAlertB() { alert(‘B’); }
function fHandleActionSelection(nSelect)
{
var iOptionIndex = nSelect.selectedIndex;
if (iOptionIndex > 0) { //skip over ‘Actions’
var sFnName = nSelect.options[iOptionIndex].value;
eval(sFnName+”()”);
}
}
</script>
</head>
<body>
<select onchange=”fHandleActionSelection(this)”>
<option>Actions</option>
<option value=”fAlertA”>a</option>
<option value=”fAlertB”>b</option>
</select>
</body>
</html>

Showing and hiding rows of a table

Great advice here:
http://blog.delaguardia.com.mx/index.php?op=ViewArticle&articleId=28&blogId=1

In FF1.5, if a <tr>’s style is changed from display:none to display:block, the row doesn’t appear correctly; for example, a <textarea> within a <td> might appear very small.

The poor display gets worse if one toggles back and forth; for me, vertical space where the row would normally go kept growing with each toggle.

The external blog entry points out that FF1.5 uses display:table-row for displaying, so one might do this:

  try {
    e.style.display = “table-row”;
  } catch (e) { //for IE, etc
    e.style.display = “block”;
  }

“Internet Explorer cannot open the Internet site…Operation aborted”

There was another problem that just appeared today where IE was popping an error saying “Internet Explorer cannot open the Internet site…Operation aborted”. Web search indicated people saw a similar problem when using the Google Maps API, evidently because IE doesn’t like scripted changes to a table DOM before the rendering finishes:

http://vidmar.net/weblog/archive/2005/08/22/2121.aspx

http://www.ryangrant.net/archives/internet-explorer-cannot-open-the-internet-site-operation-aborted-google-map-api

The suggested change was to wrap the JS inside a setTimeout with wait of 1ms. That worked for me.

Unspecified error for createStyleSheet()

Our rich text editor (RTE) was working in IE just yesterday, at least from my dev server. But once installed in QA, a JS error was being popped whenever the Compose page loaded, and the error indicated M$ method createStyleSheet(), which is called on the RTE iframe’s doc object. If one takes the option to debug offered by the error popup, VisualStudio can only say “unspecified error”, but then the RTE becomes usable!

This suggested a timing problem, and sure enough, a web search turned up problems if one calls createStyleSheet() before the doc obj’s readyState property reaches “complete”:

http://dojotoolkit.org/pipermail/dojo-interest/2006-May/008587.html

To workaround this, one could just keep trying:

function foo (sCssPath) {

try {

eDoc.createStyleSheet(sCssPath);

} catch() {

setTimeout(“foo(‘”+sCssPath+”‘)”, 10);

}

}

But that runs the risk of looping forever. A better way might be to use the M$-only onReadyStateChange handler:

if (bIE) {

if (eDoc.readyState == “complete”) {

eDoc.createStyleSheet(sCssPath);

} else {

eDoc.onreadystatechange = function() {

if (eDoc.readyState == “complete”) {

eDoc.createStyleSheet(sCssPath);

}

};

}

}

Details at MSDN

Window.onload and document.body.onload are the same

I’m used to coding with window.onload but while integrating code from someone else I found references to document.body.onload, and I thought this must be some other event.  But on page 135 of “Dynamic HTML” by Goodman, he says:

by a quirk of HTML tag structure, all window object event handlers are associated with the BODY element

JavaScript debugging

Copied from someone’s email:
This link has great info, tips, tools to debug Dojo and JavaScript, etc.

http://dojo.jot.com/DebuggingJavascript

I believe some of you asked how to do step-thru debugging of individual JS files that use the Dojo toolkit. You have to set “djConfig.debugAtAllCosts=true” and make sure the page has the “dojo.hostenv.writeIncludes();” statement added in a script element. (I believe it has to be in the head section.)

Firefox 1.5 ignores changing tabIndex of input type=file

One can change the tabIndex of a file input in FF1.5 and verify the value has changed, but the browser will ignore the change and use whatever value was staticly defined at page load.

As a workaround, see if you can define ‘tabindex’ for all items in the markup. If you’ll be dynamicly adding non-file inputs, set their tabIndex to be the same as whatever they should come after in tab order — browsers use doc order to break ties in tabIndex values. To dynamicly add file inputs, put something like this in the markup:

  <input type=file id=file0 tabindex=N onchange… /><span id=file1container></span>

Then, when you add a new file input, assign to the innerHTML property of the span rather than using createElement. (You probably also want to style the old input as display:none, depending on what you’re trying to do.)  The tabindex of the new input can be N also.

UPDATE: Once the file input is filled, one might want to take it out of the tab order. Setting tabIndex = -1 has no effect in FF1.5, and setting the style to display:none (or visibility:hidden) will cause Safari 2.0.3 to ignore it when sending the request. I haven’t found a solution that works for all browsers.

Nonvisible file inputs are not “Accessible”

File inputs are pretty ugly, and can be confusing to naive users (e.g., “Should I type what I want in that box?”).  Quirksmode describes a nicer solution that mail.aol.com (Compose) happens to use:
http://www.quirksmode.org/dom/inputfile.html

But if one cares about Big-A accessibility, such a solution won’t work for users with normal vision who are limited to the keyboard (no mice), such as those with carpal tunnel syndrome.  The reason it won’t work is that such users rely on tab order, and tabbing into an invisible file input consumes 2 tabs before one sees any visible result — the user won’t know they are on top of the Browse button.

One might suggest putting the nonfunctional button in the tab order, and when it receives focus, call click() on the nonvisible file input. But in my experiments, click() did not trigger a FileOpen dialog.

One might also suggest faking focus on the nonfunctional button by drawing a rectangle around it when the nonvisible file input receives focus.  But remember that file inputs consume 2 tabs — it might make sense to draw the rectangle on the second tab, when focus is on the Browse button, but what about the first tab?  Even if there are separate events from the file input from the tabs, which seems doubtful, what would one display for the first tab?

A decent compromise is to get rid of the nonfunctional button and make the file input visible.  But like the mail.aol.com use, hide the inputs once they are used and show a checkbox with the filename instead, with focus moved to this checkbox (so blind users will be aware of the result of their file selection).

IEDeveloperToolbar almost as useful as Firebug

I was just told that there’s an IE Developer Toolbar:
http://www.windowsmarketplace.com/details.aspx?view=info&itemid=2695980

At first glance, it provides a significant fraction of the utility of Firebug, such as showing DOM structure changes post-load. It also has a “Trace Style” feature, evidently for revealing the cascade of styles that apply to a particular element, but when I tried it all it did was open a window displaying my stylesheet.

It does not appear to support live editing of markup or styles.

Write better JS by watching YUI Theater

Yahoo has a great set of videos about JS: http://developer.yahoo.com/yui/theater/

The ones by Douglas Crockford — “The JavaScript Programming Language”, “An Inconvenient API: The Theory of the DOM”, and “Advanced JavaScript” — are intended to be watched in that order, but I think watching the DOM one first helps to clarify what happens in the browser when JS is run.

btw, Yahoo Video has no rewind/forward capability, so you might want to download the slides as well (linked next to each video).

IE JS doesn’t support indexOf() for arrays

Firefox supports indexOf() for arrays, but IE doesn’t (at least IE7 doesn’t). To work around this, write your own version…maybe like this:

function fiArrayContains(ax, xTarget) {

var n;
if (fbIsArray(ax)) {

n = ax.length;
for (i=0; i < n; i++) {

if (ax[i] == xTarget) {

return i;

}

}

}
return -1;

}

function fbIsArray(x) {

return fbIsObject(x) && x.constructor == Array;

}
function
fbIsObject(x) {

return (typeof x == ‘object’ && !!x) || fbIsFunction(x);

}
function
fbIsFunction(x) {

return typeof x == ‘function’;

}