background color with mouseover/our in IE6 (Win 2K) but the response
is fine (fast) in Firefox. Why? The code is below. Sorry about the
length.
<html>
<head>
<title>Rapid Blocking Interface</title>
<style>
.calendar {
position:relati ve;
cursor:default;
}
.calendarHeader {
background-color:lightgree n;
text-align:center;
font-family:sans-serif;
width:140;
}
.calendarRow {
height:30;
}
#calendar1 {
top:20;
left:10;
background-color:white;
}
#appointment {
position:absolu te;
width:300;
height:200;
background-color:lightyell ow;
border:2px black solid;
font-weight:bold;
font-family:sans-serif;
visibility:hidd en;
}
#output {
position:absolu te;
top:35;
left:750
}
#clear {
position:absolu te;
top:460;
left:750;
width:80;
background-color:lightgrey ;
border:2px black solid;
color:black;
text-align:center;
font-weight:bold;
font-family:sans-serif;
cursor:default;
}
</style>
</head>
<body>
<table id='calendar1' class='calendar ' border='1' cellpadding='0'
cellspacing='0' >
<tr>
<td class="calendar Header">0</td>
<td class="calendar Header">1</td>
<td class="calendar Header">2</td>
<td class="calendar Header">3</td>
<td class="calendar Header">4</td>
</tr>
<tr class='calendar Row'>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class='calendar Row'>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class='calendar Row'>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class='calendar Row'>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class='calendar Row'>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class='calendar Row'>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class='calendar Row'>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class='calendar Row'>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class='calendar Row'>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class='calendar Row'>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class='calendar Row'>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class='calendar Row'>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class='calendar Row'>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class='calendar Row'>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class='calendar Row'>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class='calendar Row'>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class='calendar Row'>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class='calendar Row'>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</table>
<div id="output"><te xtarea cols=25 rows=25></textarea></div>
<div
id="clear"
onmousedown="re turn false;"
onclick="docume nt.getElementBy Id('output').fi rstChild.value = '';"
>CLEAR
</div>
<div
id="appointment "
class="draggabl e"
onclick="this.s tyle.visibility = 'hidden';"
>
</div>
<script>
(function () {
var calendar = document.getEle mentById('calen dar1'),
rows = calendar.getEle mentsByTagName( 'tr'),
slots = calendar.getEle mentsByTagName( 'td');
/*debug*/ var output = document.getEle mentById('outpu t').firstChild;
/*debug*/ output.value = '';
var apt = document.getEle mentById('appoi ntment');
apt.appendChild (document.creat eTextNode(''));
function addSlotControl( el) {
var sc = document.create Element('div');
sc.style.positi on='relative';
sc.style.backgr oundColor='ligh tgrey';
sc.style.border Width='1px';
sc.style.border Color='black';
sc.style.border Style='solid';
sc.style.margin ='0px';
sc.style.paddin g='0px';
sc.style.visibi lity='hidden';
sc.style.top=0;
sc.style.left=1 00;
sc.style.height =13;
sc.style.width= 28;
sc.style.textAl ign='center';
sc.style.fontSi ze=10;
sc.style.fontFa mily='sans-serif';
sc.appendChild( document.create TextNode('SC')) ;
el.appendChild( sc);
}
var selectMode = false,
initialControlS tate,
columnSelected,
firstRowSelecte d,
previousRowSele cted,
lastRowSelected ,
selectionCancel led,
downOn = null;
function mousedownHandle r(e) {
e.returnValue = false;
if (e.preventDefau lt) {e.preventDefau lt();}
var target = getEventTarget( e);
if (target.nodeNam e !== 'DIV') {
if (target.nodeNam e === 'TD') {
downOn = target;
}
return false;
}
addEvent(calend ar, 'selectstart', selectStartHand ler, false);
var slot = target.parentNo de;
selectMode = true;
selectionCancel led = false;
initialControlS tate = target.style.ba ckgroundColor;
columnSelected = slot.cellIndex;
firstRowSelecte d = lastRowSelected = slot.parentNode .rowIndex;
slot.firstChild .style.visibili ty = 'hidden';
slot.style.back groundColor
= (initialControl State === 'lightgrey')? '#FF9966':'#FFC C99';
return false;
}
/
*************** *************** *************** *************** ***********
Distinguishing onmouseover/out of child elements from those of the
parent element.
Mouseover fires first but mouseout fires when the mouse moves over
the child (DIV) element. The problem is not just about bubbling,
because when you move the mouse over the DIV, you are not moving out
of anything contained in the table cell (TD) nor are you moving out
of the area contained by the TD. A mouseout event fires simply
because a mouseover event fires for another element.
See: http://www.faqts.com/knowledge_base/view.phtml/aid/1606
http://www.quirksmode.org/js/events_mouse.html
http://www.dynamic-tools.net/toolbox...eLeaveOrEnter/
Also, the try/catch blocks handle a related version of the
"Permission denied to get property HTMLDivElement. parentNode"
bug in Firefox/Mozilla. Moving the mouse cursor fast enough from the
grid over the textarea will cause this bug to occur.
See: https://bugzilla.mozilla.org/show_bug.cgi?id=208427
https://bugzilla.mozilla.org/show_bug.cgi?id=214340
*************** *************** *************** *************** ***********/
function mouseoverHandle r(e) {
if (selectionCance lled) { return; }
var err, target = getEventTarget( e);
if (target.nodeNam e !== 'TD'
&&
target.nodeName !== 'DIV') { return; } // Mouse did not enter
// calendar slot.
/** Get the element the mouse comes from. **/
var relTarget = e.relatedTarget || e.fromElement;
try {
if (relTarget.pare ntNode === target // Mouse moves
|| // from child
target.parentNo de === relTarget) { return; } // over parent
} // target element
catch (err) { return; } // or vice versa.
/** Mouse actually entered TD. Handle event. **/
if (target.nodeNam e === 'DIV') { target = target.parentNo de; }
if (target.classNa me === 'calendarHeader ') { // Mouse moved into
if (selectMode) { cancelSelection (); } // calendar header.
}
else if (!selectMode) {
target.style.ba ckgroundColor
= (target.firstCh ild.style.backg roundColor === 'lightgrey')?
'lightyellow':' lightgrey';
target.firstChi ld.style.visibi lity = "visible";
}
else if (target.cellInd ex === columnSelected)
{
// First detect missed mouse events with fast cursor movement.
var rowT = target.parentNo de.rowIndex,
rowRT = (relTarget.node Name === 'TD')?
relTarget.paren tNode.rowIndex: relTarget.paren tNode.parentNod e.rowIndex;
if (rowRT !== undefined
&&
Math.abs(rowRT - rowT) 1) // Cancel if slot events missed.
{
cancelSelection ();
return;
}
previousRowSele cted = lastRowSelected ;
lastRowSelected = target.parentNo de.rowIndex;
var slot,
sc,
vector = Math.abs(lastRo wSelected - firstRowSelecte d) -
Math.abs(previo usRowSelected - firstRowSelecte d);
if (vector 0) // Moving away from first selection.
{
sc = target.firstChi ld;
sc.style.visibi lity = 'hidden';
target.style.ba ckgroundColor
= (sc.style.backg roundColor === 'lightgrey')?
'#C6E2FF':'#9FB 6CD';
}
else if (vector < 0) // Moving toward first selection.
{
slot = rows[previousRowSele cted].cells[columnSelected];
slot.style.back groundColor
= (slot.firstChil d.style.backgro undColor === 'lightgrey')?
'white':'lightg rey';
}
}
}
function mouseoutHandler (e) {
if (selectionCance lled) { return;}
var err, target = getEventTarget( e);
if (target.nodeNam e !== 'TD'
&&
target.nodeName !== 'DIV') { return; } // Mouse did not exit
// calendar slot.
/** Get the element the mouse goes to **/
var relTarget = e.relatedTarget || e.toElement;
try { // Mouse moves
if (relTarget.pare ntNode === target // to child
|| // out from
target.parentNo de === relTarget) { return; } // parent target
} // or vice versa.
catch (err) {
if (!selectMode
&&
target.style.ba ckgroundColor) // IE related issue.
{
target.style.ba ckgroundColor
= (target.firstCh ild.style.backg roundColor === 'lightgrey')?
'white':'lightg rey';
target.firstChi ld.style.visibi lity = "hidden";
}
return;
}
/** Mouse actually left TD. Handle event. **/
if (target.nodeNam e === 'DIV') { target = target.parentNo de; }
if (target.classNa me === 'calendarHeader ') { return; }
if (!selectMode) {
target.style.ba ckgroundColor
= (target.firstCh ild.style.backg roundColor === 'lightgrey')?
'white':'lightg rey';
target.firstChi ld.style.visibi lity = "hidden";
}
else if (relTarget.cell Index !== columnSelected)
{ cancelSelection (); }
}
function mouseupHandler( e) {
var coord, target = getEventTarget( e);
if (target.nodeNam e === 'DIV')
{
target = target.parentNo de;
}
if (target.nodeNam e === 'TD'
&&
target.parentNo de.className === 'calendarRow')
{
if (selectMode) {
if (!selectionCanc elled) { finalizeSelecti on(); }
}
else if (downOn === target) {
if (target.style.b ackgroundColor !== 'lightgrey') {
apt.innerHTML = ' ' + target.parentNo de.rowIndex + ',
'+ target.cellInde x;
apt.style.left = e.pageX || e.clientX + document.body.s crollLeft
+ document.body.c lientLeft;
apt.style.top = e.pageY || e.clientY + document.body.s crollTop +
document.body.c lientTop;
apt.style.visib ility = 'visible';
}
downOn = null;
}
}
selectMode = selectionCancel led = false; // Whether true or false,
calendar.onsele ctstart = null; // set to false.
}
function selectStartHand ler(e) {
e.returnValue = false;
return false;
}
function finalizeSelecti on() {
var c = columnSelected, r, slot, slotBgC, scBgC;
if (initialControl State === 'lightgrey') {
slotBgC = 'lightgrey';
scBgC = 'white';
}
else {
slotBgC = 'white';
scBgC = 'lightgrey';
}
if (firstRowSelect ed <= lastRowSelected ) {
for (r = firstRowSelecte d; r <= lastRowSelected ; r++) {
(slot = rows[r].cells[c]).style.backgro undColor = slotBgC;
slot.firstChild .style.backgrou ndColor = scBgC;
}
}
else {
for (r = firstRowSelecte d; r >= lastRowSelected ; r--) {
(slot = rows[r].cells[c]).style.backgro undColor = slotBgC;
slot.firstChild .style.backgrou ndColor = scBgC;
}
}
initialControlS tate = null;
firstRowSelecte d = null;
lastRowSelected = null;
columnSelected = null;
}
function cancelSelection () {
var c = columnSelected, r, slot, slotBgC;
selectionCancel led = true;
if (firstRowSelect ed <= lastRowSelected ) {
for (r = firstRowSelecte d; r <= lastRowSelected ; r++) {
slotBgC = ((slot =
rows[r].cells[c]).firstChild.st yle.backgroundC olor === 'white')?
'lightgrey':'wh ite';
slot.style.back groundColor = slotBgC;
}
}
else {
for (r = firstRowSelecte d; r >= lastRowSelected ; r--) {
slotBgC = ((slot =
rows[r].cells[c]).firstChild.st yle.backgroundC olor === 'white')?
'lightgrey':'wh ite';
slot.style.back groundColor = slotBgC;
}
}
initialControlS tate = null;
firstRowSelecte d = null;
lastRowSelected = null;
columnSelected = null;
}
function elXY(el) {
var c = {x:0, y:0};
while (el) {
c.x += el.offsetLeft;
c.y += el.offsetTop;
el = el.offsetParent ;
}
return c;
}
function evtXY(e) {
return {
x:e.offsetX || e.clientX + window.pageXOff set,
y:e.offsetY || e.clientY + window.pageYOff set
}
}
function addEvent(el, evtType, listener, captures) {
if (el.addEventLis tener) {
el.addEventList ener(evtType, listener, captures);
return true;
}
else if (el.attachEvent ) {
return el.attachEvent( 'on' + evtType, listener);
}
else {
el['on' + evtType] = listener;
}
}
function getEventTarget( e) {
return (window.event)? window.event.sr cElement:(e)? e.target:null;
}
function stopBubbling(e) {
if (!e) { var e = window.event; }
e.cancelBubble = true;
if (e.stopPropagat ion) { e.stopPropagati on(); }
}
for (var i=0; i < slots.length; i++) {
if (slots[i].className !== 'calendarHeader ') {
addSlotControl( slots[i]); // Add slot control as
} // slots first child.
}
addEvent(docume nt, 'mouseup', mouseupHandler, false);
addEvent(calend ar, 'mousedown', mousedownHandle r, false);
addEvent(calend ar, 'mouseover', mouseoverHandle r, false);
addEvent(calend ar, 'mouseout', mouseoutHandler , false);
})();
</script>
</body>
</html>