I wouldn't have thought so either but it's what I'm
getting. Maybe it would be better if I include the
script.
It almost always is.
function mouse(){
y1 = event.clientY;// - window.pageYOffset;
x1 = event.clientX;
}
There you go, Opera 6 returns co-ordinates relative to the page for
clientX/Y while Opera 7 (correctly) returns co-ordinates relative to the
client area.
document.onmousemove=mouse;
Netscape 4 (but preferably not later Netscape versions (though they do
support the function)) requires calls to document.captureEvents if you
want to follow mouse movement at the document level.
function move_these(){
temp.top = y2 + window.pageYOffset;
temp.left = x2;
}
If the mouse co-ordinates you are using are page relative you do not
need to adjust for the scrolling values at this point, if you use client
co-ordinates then you do need to adjust.
But the CSS units value comes in at this point. On standards compliant
browsers a string value should be assigned to the top and left style
properties with appended units. OTOH older browsers prefer the values to
be provided as numbers. My strategy for dealing with this problem is
based on using typeof to test one of style.top or style.left to see if
it is of string type or numeric. If it is a string then it is best to
provide CSS units, if it is a number then it is best to assign a number.
I do this by assigning a value to a suitably scoped variable based on
the typeof test:-
var posMod = (typeof temp.top == 'string')?'px':0;
-and then when a value is to be assigned to top or left (or any other
style value that need similar handling) I use the + operator:-
temp.top = y2 + posMod;
- the - y2 - value is a number and - posMod - is either the number zero
or it is the string 'px' so the action of the + operator depends on the
type of posMod. If - posMod - is zero then - + - does addition and
adding zero to a number results in an unchanged number, and that is
assigned to the style property. But if - posMod - is the string 'px'
the - + - operator does string concatenation, type-converting the - y2 -
value to a string and then appending 'px' to it, providing the desired
string value with the CSS units.
function delay(){
y2 = y3 += (y1 - y3) * 0.1;
x2 = x3 += (x1 - x3) * 0.1;
move_these();
setTimeout('delay()',50);
}
If - delay - always calls - delay - (without the option of being
cancelled) it would be wroth looking into the setInterval function as an
alternative.
I didn't know that. Would..
((event.clientY)||(event.pageY&&event.clientY))
?event.clientY:event.clientY-window.pageYOffset;
..do?
Over the years I have tried out various strategies for reading the mouse
co-ordinates, the following is the latest version of my cross browser
document.onmousemove following object:-
var MoveFollow = (function(){
var global = this;
var theOne = {
getPageX:function(){
return ((readScroll.scrollLeft|0) -
(readScroll.clientLeft|0) + XY.x);
},
getPageY:function(){
return ((readScroll.scrollTop|0) -
(readScroll.clientTop|0) + XY.y);
},
getPageXY:function(){
return {x:this.getPageX(),y:this.getPageY()};
},
upDate:function(ev){
mm(ev);
}
};
var XY = {x:0,y:0};
var readScroll = {scrollTop:0,scrollLeft:0,
clientLeft:0,clientTop:0};
var eventInited = false;
var posReadX = 'pageX';
var posReadY = 'pageY';
function mm(e){
e = e||global.event;
XY.x = e[posReadX];
XY.y = e[posReadY];
};
function initEvent(ev){
ev = ev||global.event;
if(ev){
if(typeof ev.pageX != 'number'){ //Opera 7 has pageX
posReadX = 'clientX';
posReadY = 'clientY';
if(!global.opera){ //Not an Opera browser
if((typeof document.compatMode == 'string')&&
(document.compatMode.indexOf('CSS') != -1)&&
(document.documentElement)){
readScroll = document.documentElement;
}else if(document.body){
readScroll = document.body;
}
}
}
setUpOnMouse(mm);
mm(ev);
eventInited = true;
}else{
setUpOnMouse(initEvent);
}
};
function setUpOnMouse(f){
if(document.onmousemove != f){
document.onmousemove = f;
if((document.captureEvents)&&(global.Event)&&
(document.layers)&&(typeof Layer == 'function')){
document.captureEvents(Event.MOUSEMOVE);
}
}
};
initEvent();
return (function(){
return theOne;
});
})(); //simultaneously define and call (one-off)!
The - MoveFollow - global variable is assigned a function and once it
has been assigned any other code can call the - MoveFollow - function,
which will return a reference to an object that represents a common
interface to the onmousemove events (cross-browser). The bulk of the
testing and configuration work is done as this script initialises itself
so once it is running it is very efficient.
The reference to the interface is acquired as:-
var mouseMoveFollower = MoveFollow();
-the the latest mouse X and Y co-ordinates (relative to the HTML page)
are retrieved using the interface's getPageX/Y methods:-
var pageXcord = mouseMoveFollower.getPageX();
/* and */
var pageYcord = mouseMoveFollower.getPageY();
If you can understand the code (with its inline function expression
call, nested functions, and so on) you should be able to understand how
the code decides which values to read from the event objects. It is the
only code that I use that has any interest in which browser is on use
specifically in order to cope with the incorrect reporting of clientX/Y
in Opera 6. Which is done by checking Opera's global - opera - property.
That isn't a problem for Opera 7, which has the pageX/Y properties on
the event object and the code prefers to use those if available.
Richard.