NS6 supports both event bubbling (IE4+) and event capturing (NS4). You may directly attach an event to an element, for example:
document.getElementById("test").onmouseover=
or
<div id="test" onMouseover=".....">
and expect the browser to not only react to it, but the event to bubble upwards.
So we need to tell the browser when to stop dragging
document.onmouseup=new Function("dragapproved=false")
The DOM interprets all user action very differently from the user. To you, clicking on a link is just that, but to the DOM, an entire process is invoked that takes the action on a trip around the block and back. Ok, more explanation is definitely needed.
Let's take the simple user action of moving the mouse over a link as an example. To the DOM, the following events in fact took place, and in that order:
1) You moved your mouse over the document
2) You moved your mouse over any tags containing the target <A> tag
3) You moved your mouse over the <A> tag in question
No, we're not quite yet done. From here the event then travels back:
4) You moved your mouse over any tags containing the target <A> tag
5) You moved your mouse over the document. (the end).
Yes, the DOM likes to get very technical. Using a diagram, here's what just happened:
Mouse over document -->Mouse over any containment tags of <A> -->
Mouse over destination <A> -->
Mouse over any containment tags of <A> --> Mouse over document
The above "roundtrip" model is used by the DOM to interpret most events. We call the event as it travels to the intended element event capture, and as it travels back event bubble.
-Event Capture
So, event capture basically refers to the process of an event as it travels
to its destination element. Actually, it further refers to the ability to "capture",
or intercept this event.
If event capture sounds suspiciously familiar, it should. NS4 has long supported event capture, through the syntax:
element.captureEvents()
In other words, when you click on a link in NS4 for example, this event first travels through the document, then incrementally downwards to all containing elements of the link until eventually reaching the link itself.
-Event bubble
Event bubble is the exact opposite of event capture, and points to the traveling upwards of an event from the source element to the topmost, or document. IE4 revolutionized event handling by being the first major browser to support event bubble. An event such as clicking on a link causes it to travel upwards, visiting all of the link's container tags until eventually reaching the top of the document source.
Consider the following HTML code:
<table onClick="alert('Hello!')">
<b><a href="#">This is some text</a></b>
</table>
Here we define an onClick event handler inside the TABLE. With event bubbling,
merely clicking on the containing link fires this event (and subsequently the
alert message), since the event traverses upwards from A to B and eventually
reaching TABLE.
NS6 fully embraces the proposed DOM event flow- event capture then event bubble. To tame this circling beast, a concept for attaching event handlers is introduced- event listeners. Oh no, here comes an earful. Actually, event listeners can be summed up using just two methods.
object.addEventListener(event, function, capture)
object.removeEventListener(event, function, capture)
-event should contain the event you wish to detect, such as click (onclick
minus the "on" prefix)
-function should contain the reference call to the function to execute for this
event, such as dothis (dothis() minus the parenthesis)
-capture should contain the Boolean value "true" or "false";
A value of "true" causes function to be executed when the event is
detected at the capture phase. A value of "false" causes function
to be executed when event is at bubble phase.
The first method assigns an event handler, while the second obviously allows you to then remove it.
Let's use this knowledge to attach an onMousever event to a DIV in NS6:
<div id="test">
Some text over div
</div>
<script>
function alertit(){
alert("You moved your mouse over me!")
}
document.getElementById("test").addEventListener("mouseover",alertit,false)
</script>
Moving your mouse over the DIV now will cause an alert message to popup.
One cool thing about addEventListener() is that it can be used multiple times to attach multiple functions to the same event for the same element. For example, we can have 3 separate onMouseover events for the DIV above:
document.getElementById("test").addEventListener("mouseover",alertthis,false)
document.getElementById("test").addEventListener("mouseover",alertdat,false)
document.getElementById("test").addEventListener("mouseover",alerttidat,false)
and all three will be responded to onMouseover. Finally two scripts can both apply the same event handler to an element without the former being cancelled out.
Using object.removeEventListener(), you can dynamically remove an event handler added using its counterpart. When doing so, the 3 parameters must be identical to the ones used to add the event.
Assigning event handlers in IE5+
In IE5, the DOM is more simplistic in that it focuses simply on events bubbling up. In other words, the event flow of IE5+ is half that of NS6's. Good thing it retains the better half :)
Two proprietary methods are supported for assigning event handlers in the DOM of IE5:
object.attachEvent(eventname, function)
object.detachEvent(eventname, function)
-eventname should contain the full event name you wish to detect, such as onclick
-function should contain the reference call to the function to execute for this
event, such as dothis (dothis() minus the parenthesis)
Let's replicate the above <DIV>, but attach the event IE5 style:
<div id="test">
Some text over div
</div>
<script>
function alertit(){
alert("You moved your mouse over me!")
}
document.getElementById("test").attachEvent("onmouseover",alertit)
</script>
var nsx
var nsy
var nstemp
function drag_drop(name){
temp=eval(name)
temp.captureEvents(Event.MOUSEDOWN | Event.MOUSEUP)
temp.onmousedown=go
temp.onmousemove=drag
temp.onmouseup=stop
}
function go(e){
temp.captureEvents(Event.MOUSEMOVE)
nsx=e.x
nsy=e.y
}
function drag(e){
temp.moveBy(e.x-nsx,e.y-nsy)
return false
}
function stop(){
temp.releaseEvents(Event.MOUSEMOVE)
}
</script>
function drags(e){
if (e.target.className=="drag"){
dragapproved=true
z = e.target
temp1=parseInt(e.target.style.left+0)
temp2=parseInt(e.target.style.top+0)
x= e.clientX
y= e.clientY
document.onmousemove=move
return false
}
}
while (event.srcElement.tagName!=topelement&&event.srcElement.className!="drag"){
event.srcElement= event.srcElement.parentElement
}
the browsers are getting lost in the html tags -- this tells them to ignore
the tag, unless our layer's parent is the <html> for netscape6 and <body>
for ie, AND the layer name is "drag".
x and y are where the mouse gets clicked
temp1 and temp2 are the spots where the layers are to start
z is the division object we clicked -- in this case "drag"
document.onmousemove=move
move is the next executable function we go to
if (dragapproved){
if we have the correct layer, then we will move our layer where the mouse goes
e.target.style.left = temp1 + e.clientX - x
e.target.style.top = temp2 + e.clientY - y
e.target.style.left is where the layer's leftmost corner is going to go
e.target.style.top is where the layer's topmost corner is going to go
temp1 + e.clientX - x
e.clientX is where the mouse is now, x is where it started
temp1 is where the layer started
so - temp1 (where the layer started) plus where the mouse is now, minus where
the mouse started (so our mouse isn't skipping to some predefined spot.)
IE5.x/Win Supports a:hover and appropriate onMouse* events for the <a>
tag.
IE5.x/Mac Supports a:hover and appropriate onMouse* events for the <a>
tag.
NS4.x/Win Does not support a:hover, but supports appropriate onMouse* events
for the <a> tag.
NS6.x/Win Supports a:hover and appropriate onMouse* events for the <a>
tag.
Recommended Solution
Image-driven mouseovers consume more bandwidth but are more reliable across
a broad array of browsers. If you use CSS and the a:hover property, your pages
load more quickly but NS4.x will be excluded. For maintainability and bandwidth
reasons, I prefer the a:hover approach. The major browsers support the onMouse*
events but you will not be able to get the cheap a:hover effect to work on NS4.x.
Image-driven mouseovers consume more bandwidth but are more reliable across a broad array of browsers. If you use CSS and the a:hover property, your pages load more quickly but NS4.x will be excluded. For maintainability and bandwidth reasons, I prefer the a:hover approach. The major browsers support the onMouse* events but you will not be able to get the cheap a:hover effect to work on NS4.x.