AJAX freakshow: Drag ‘n’ Drop events And Preventing Text-Selection in IE.

Today a coworker of mine mentioned that he wanted to develop a drag ‘n’ drop web interface using JavaScript, DHTML, and Ajax for a farm asset management application he has built in Python. Yes, a farm asset management application.

What?

Anyhow, about 60 minutes later I had come up with this example:

Ajax/DHTML DnD

You can drag the gray box around the page, and if you drop in on the orange “hotspot”, JavaScript will generate an HTTP request back to a small PHP script (I know…) on the server. This script doesn’t actually need to be a script at the moment, cuz it doesn’t do anything but return a canned response. But still.

All CSS, JavaScript and (valid) XHTML (1.0 Strict) are embedded directly in the page linked above.

The example works in all modern browsers:

  • IE 6 Win
  • IE 5.5 Win
  • IE 5.0 Win
  • Firefox/Mozilla
  • Camino 0.8+
  • Safari 1.1+
  • OmniWeb 5+
  • Opera 7+
  • Netscape Navigator

Note the use of a very little-known technique here to make DnD better in IE… When doing DnD in IE the conventional way (regular ole JavaScript onmousedown, onmousemove, onmouseup event-handlers rather than the proprietary IE drag event handlers whose names I can’t recall and which don’t work in many other browsers anyway)… you will experience a very annoying “text-selection”. Whenever you drag an html element across some underlying text on the page, the text will be selected just like during a normal mouse drag. This is not desireable in a DnD application.

There is a way to prevent this madness!

I’ve never seen this trick referenced before, and I slaved for days to figure it out at my last job… to prevent unwanted text selection amid DnD operations in IE, you have to add two proprietary IE event handlers to the <body> tag:


<body onselectstart='return false;' ondrag='return false;'>

That will prevent the unsightly text selection.

Big problem here though… if you are using valid XHTML Strict (you are using valid XHTML Strict, right? Everyone’s doing it… try it, you’ll like it!), this will break the validity of your document as these event handlers are proprietary and not in the XHTML spec. No problem, just do this:


<body onload='windowLoaded(event);'>

And then put this in your JavaScript for the page:


function windowLoaded(evt) {
    // prevent IE text selection while dragging!!!
    // Little-known trick!
    document.body.ondrag = function () { return false; };
    document.body.onselectstart = function () { return false; };
}

Another little gem buried in the example is this function that will set the opacity of a given html element (DOM element node reference) to a given float value dynically using JavaScript:


function setOpacity(node,val) {
    if (node.filters) {
        try {
            node.filters['alpha'].opacity = val*100;
        } catch (e) { }
    } else if (node.style.opacity) {
        node.style.opacity = val;
    }
}

That function works in IE 6 and EOMB (Every Other Modern Browser) and prevents a JavaScript error in IE 5.0 and 5.5. It might actually be better to do this kind of style tinkering by toggling the className properties for the element references, but whatevs.

As shown, the example has some accessibility issues… now, as long as you have JavaScript enabled, you can never select text on the page in IE. You could easily get around this by dynamically setting these event handlers on document.body in the drag start and drag end methods instead. This would make text unselectable during dragging, but selectable at other times.

Comments are closed.