The suprising thing is that almost without exception, I haven't found a single Javascript resource that always gets the right answers. Take the simple problem of locating the mouse. Search on Google for
mouse position javascript and the first page of links all take you to solutions that will fail under one circumstance or another.Bad examples include:
- Retrieving mouse-x and mouse-y in two separate functions, both of which have to traverse the same document model.
- Relying on browser detect functions to decide how to access properties
- Ignoring browser types completely and only functioning in IE
- Only solving the first half of the problem - finding the mouse on the page. If you don't know where your document element is, you have no context for the rest of your code.
- Failing to handle the case where the document has been scrolled
- Failing to handle the case where your event occurs within an IFRAME
Of all of these, Quirksmode only falls into the last trap. If you're handling an event from an IFRAME, you should be careful to account for the scroll offset of the frame itself and not the document that the event handler resides in. This function does exactly that:
function mousePos(evt, relativeTo) {
var xPos, yPos;
if (evt.pageX || evt.pageY) {
// Netscape
xPos = evt.pageX;
yPos = evt.pageY;
}
else if (evt.clientX || evt.clientY) {
// Probably IE
var docn = evt.srcElement ? evt.srcElement.ownerDocument : evt.target.ownerDocument;
xPos = evt.clientX + docn.body.scrollLeft + docn.documentElement.scrollLeft;
yPos = evt.clientY + docn.body.scrollTop + docn.documentElement.scrollTop;
}
var locn = {x: xPos, y: yPos};
if( relativeTo ) subtract( locn, relativeTo );
return locn;
}
function sutract( point1, point2 ) {
point1.x = point1.x - point2.x;
point1.y = point1.y - point2.y;
}
Note that the function takes the event object and an optional parameter for the position of the element that you want to find the mouse location relative to.
Now, all you need to know is where that element is relative to the document it resides in, and you can get a fix on your mouse event. Here's the code, which takes account of elements that can be scrolled.
function findPosition( obj ) {
var xPos = yPos = 0;
var start = obj;
while (obj && obj.offsetParent) {
xPos += obj.offsetLeft;
yPos += obj.offsetTop;
// Don't include scroll offsets for myself, or my parent document
if( obj != start && obj != obj.ownerDocument.body && obj != obj.ownerDocument.documentElement ) {
xPos -= obj.scrollLeft;
yPos -= obj.scrollTop;
}
obj = obj.offsetParent;
}
return {x: xPos, y: yPos};
}
0 comments:
Post a Comment