Event Identifiers - ClientX and ClientY - javascript

I am trying to better understand the usage of the event attribute clientX and clientY.
I need to find the top and left offset of the mouse pointer when it moves over a particular div . The projectImage(x) function is attached to the onmouseover of the div. x is a function argument based on which the URL of a particular image can be determined.
Now. clientX is the left offset of the pointer at the time the mouseover event happens, so what can I enter for event in event.clientX
Th function below does not work (Reported as Not Defined by the JS Console) I think because of a syntax error in the first two lines.
function projectImage(x)
{
// Should the 1st two lines (right hand side) be x.clientY and x.clientX,
// x is a function argument not event relevant to the pointer offset though
var toffset = x.clientY ; // help_me_here.clientY
var loffset = x.clientX ; // Event_Identifier_??.cleintX
var picdiv = document.getElementById("picdiv") ;
picdiv.style.position = "absolute" ;
picdiv.style.left = loffset + "px" ;
picdiv.style.top = toffset + "px" ;
picdiv.innerHTML = "<img src='" + "http://imageServer.com/" + x.split("|")[1] + "' width='30px' />" ;
picdiv.style.visibility = "visible";
}

All you have to do is pass the event object to the function (and maybe refactor the arguments a bit):
<div onmouseover="projectImage(event || window.event, 'Joey', 123);"> Joey </div>
event || window.event is needed because IE is not passing the event object as argument to the event handler and thus has to be retrieved via window.
Also change your function to be able to access the those arguments:
function projectImage(event, name, id) {
var toffset = event.clientY;
var loffset = event.clientX;
var picdiv = document.getElementById("picdiv") ;
picdiv.style.position = "absolute" ;
picdiv.style.left = loffset + "px" ;
picdiv.style.top = toffset + "px" ;
picdiv.innerHTML = "<img src='http://imageServer.com/" + id + "' width='30px' />" ;
picdiv.style.visibility = "visible";
}
Using meaningful variable names helps to understand the code easier.

As #FelixKling mentions you should be passing the event object.
I recommend switching to addEventListener/attachEvent instead of using inline events as well, I set you up an example here.
var x = document.getElementById('x');
var y = document.getElementById('y');
document.getElementById('test').addEventListener('mousemove', function(e){
x.innerHTML = 'X: ' + e.clientX;
y.innerHTML = 'Y: ' + e.clientY;
});​
If you're dead set on inline events, though, you can do it via <div onmouseover="projectImage(event,'Joey|123');"> Joey </div>

Related

Javascript mouse click coordinates

I'm having problems trying to record the exact coordinates a click was made. The first readMouseMove function is working exactly how it is supposed to. Displaying the mouse coordinates when i scroll around. The second mouseClick function should record the coordinates only when a click is made. At the moment it's the same as the function above but it seems I can only use the clientx/y event once. Would there be a way to record the mouse click without having it be relative to an object somewhere?
<script type='text/javascript'>
function readMouseMove(e) {
var xandy = 'x=' + e.clientX + " " +'y=' + e.clientY;
document.getElementById('divOne').innerHTML = xandy;
};
function mouseClick(e) {
var clickers = 'x=' + e.clientX + " " +'y=' + e.clientY;
document.getElementById('divTwo').innerHTML = clickers;
};
function clearAll() {
document.getElementById('divTwo').innerHTML = " "
};
document.onmousemove = readMouseMove;
document = mouseClick;
</script>
you are assigning a mouseClick to document object here:
document = mouseClick;
Should be:
document.onclick = mouseClick;

FInd out position of html element in iframe

I want to find out the position of an element which is in iframe. I am trying ot use:-
//Function to find the position of element on page
function getElementPosition(elem){
var posX = 0;
var posY = 0;
while(elem!= null){
posX += elem.offsetLeft;
posY += elem.offsetTop;
elem = elem.offsetParent;
console.log("In function:" + elem.tagName + " " + posX + " " + posY);
}
return { x : posX, y : posY };
}
To get the list of all elements of iframe,
var doc1 = $('#page1').get(0).contentDocument; // page1 is id of iframe element
var list1 = doc1.getElementsByTagName('*');
console.log(list1.length); // Printing correctly
var index = prompt("Enter element index");
var elem1 = list1[index];
var pos1 = getElementPosition(elem1);
console.log("Positions:" + pos1.x + " " + pos1.y);
But this is not working. Initially elem is not null but elem.offsetParent is null in every case. Am i doing some wrong ?
For some elements, it is working fine. But for some elements, offsetParent is coming null and so their offsetLeft is 0 and offetTop is 0.
Is there any other way to find out position of each element.
Thanks in advance..
You already appear to be using jQuery. Why not let jQuery do the heavy lifting for you?
http://api.jquery.com/position/
http://api.jquery.com/offset/

Setting mouse coordinates on fireEvent

I'm trying to emulate a mousemove event in a link in IE8, but I'm not sure if it's possible to set the coordinates of the mouse in the event. This is my code so far:
function Handler()
{
var dump = "";
for(var i in event)
{
dump += ("" + i) + " => " + event[i] + "\n";
}
dumper.value = "";
dumper.value = dump;
}
function Init()
{
document.getElementById("link2").attachEvent("onmousemove", function(){Handler();});
}
function Emulate()
{
var evt = document.createEventObject();
evt.x = 10;
evt.y = 10;
document.getElementById("link2").fireEvent("onmousemove", evt);
}
The event is being attached by calling the Init() function onload. When I call Emulate() the coordinates are the actual coordinates of the cursor. Am I doing something wrong or is this just not possible?
OK I just edited my question to reflect my original failing code (the one I posted was messed up). The solution was to set clientX and clientY instead. x and y will automatically get the values assigned to them:
function Emulate()
{
var evt = document.createEventObject();
evt.clientX = 10;
evt.clientY = 10;
document.getElementById("link2").fireEvent("onmousemove", evt);
}

loop into js object

i have this js object:
var tags = [{ 'x' : '42','y' : '25','id' : '1', 'linea' : '1'},{ 'x' : '378','y' : '24','id' : '2', 'linea' : '1'}];
i try to loop in this way:
for(var i = 0; i < tags.length; i++){
var x = tags[i].x -10;
var y = tags[i].y -10;
var offsetX = x + 20;
var offsetY = y + 20;
if( left >= x && left <= offsetX ){
$(myDiv).bind('click',function(){
document.location.href = 'x.php?a='+ tags[i].linea +'&b=' + tags[i].id;
}).css('cursor','pointer');
}else{
$(myDiv).unbind('click').css('cursor','none');
}
}
But i loose the first!
Is this the correcy way??
Thanks!
You don't loose the first (sounds like it was a car key). You problem is your anonymous function, that closes over its parent scope when executed( for your .bind() method). It creates, what we call, a Closure.
Its a very common mistake in ECMAscript there. You need to invoke an additional context to avoid this issue.
$(myDiv).bind('click',(function( index ){
return function() {
document.location.href = 'x.php?a='+ tags[index].linea +'&b=' + tags[index].id;
};
}( i ))).css('cursor','pointer');
If you don't do that, all of those anonymous function context will share the same parent context in their scope-chain. Without describing that too much in detail now, it'll end up that all event handlers would reference the same variable i.
Beside that, it looks like you're binding multiple click event handlers to the same element myDIV. Each handler would cause the browser to redirect to another url, so, this will bring trouble. I can't even tell if the first or the last handler will win this race.
Variable scope.. change to this and it should work fine:
var lineA = tags[i].linea;
var id = tags[i].id;
$(myDiv).bind('click',function(){
document.location.href = 'x.php?a='+ lineA +'&b=' + id;
}).css('cursor','pointer');
The problem is with i being the loop iterator, so when you click myDiv it will have the last value always.
Edit: after looking into it, I could see you are taking the wrong approach. What you are after is identifying where the user clicked inside the <div> and redirect to different location according to your array. For this, such code should work:
var tags = [{ 'x' : '42','y' : '25','id' : '1', 'linea' : '1'},{ 'x' : '378','y' : '24','id' : '2', 'linea' : '1'}];
$("#myDiv").bind('click',function(event) {
var left = event.pageX - $(this).position().left;
for(var i = 0; i < tags.length; i++){
var x = tags[i].x -10;
var y = tags[i].y -10;
var offsetX = x + 20;
var offsetY = y + 20;
if( left >= x && left <= offsetX ){
var lineA = tags[i].linea;
var id = tags[i].id;
document.location.href = 'x.php?a='+ lineA +'&b=' + id;
break;
}
}
});
The code should be pretty clear, anyway it's not possible to have only parts of the element with hand cursor - I advise you not to mess too much as it will be really complicated.
Live test case.
Edit 2: Having the "clickable" parts of the element with different cursor is easier than I initially thought, you just have to handle the onmousemove event as well and in there set the cursor:
var posLeft = $("#myDiv").position().left;
$("#myDiv").bind('click',function(event) {
var tag = GetHoveredTag(event);
if (tag) {
var lineA = tag.linea;
var id = tag.id;
document.location.href = 'x.php?a='+ lineA +'&b=' + id;
}
}).bind("mousemove", function(event) {
var tag = GetHoveredTag(event);
var cursor = (tag) ? "pointer" : "";
$(this).css("cursor", cursor);
});
function GetHoveredTag(event) {
var left = event.pageX - posLeft;
for(var i = 0; i < tags.length; i++){
var x = tags[i].x -10;
var y = tags[i].y -10;
var offsetX = x + 20;
var offsetY = y + 20;
if( left >= x && left <= offsetX )
return tags[i];
}
return 0;
}
Updated fiddle.

Javascript-moving image

How is it posible move an image from one position to other with fadeout?
I hav such functions
for hiding:
function SetOpacity(object,opacityPct)
{
// IE.
object.style.filter = 'alpha(opacity=' + opacityPct + ')';
// Old mozilla and firefox
object.style.MozOpacity = opacityPct/100;
// Everything else.
object.style.opacity = opacityPct/100;
}
function ChangeOpacity(id,msDuration,msStart,fromO,toO)
{
var element=document.getElementById(id);
var opacity = element.style.opacity * 100;
var msNow = (new Date()).getTime();
opacity = fromO + (toO - fromO) * (msNow - msStart) / msDuration;
if (opacity<0)
SetOpacity(element,0)
else if (opacity>100)
SetOpacity(element,100)
else
{
SetOpacity(element,opacity);
element.timer = window.setTimeout("ChangeOpacity('" + id + "'," + msDuration + "," + msStart + "," + fromO + "," + toO + ")",1);
}
}
function FadeOut(id)
{
var element=document.getElementById(id);
if (element.timer) window.clearTimeout(element.timer);
var startMS = (new Date()).getTime();
element.timer = window.setTimeout("ChangeOpacity('" + id + "',500," + startMS + ",100,0)",1);
}
for get current position or next position (by id of image and id of div)
function findPos(e){
var obj = document.getElementById(e);
var posX = obj.offsetLeft;var posY = obj.offsetTop;
while(obj.offsetParent){
posX=posX+obj.offsetParent.offsetLeft;
posY=posY+obj.offsetParent.offsetTop;
if(obj==document.getElementsByTagName('body')[0]){break}
else{obj=obj.offsetParent;}
}
alert(posX+'-'+posY);
}
the first position is position of image, and next - is position of div
The easiest approach with minimal code will be to use jQuery and use the animate function mate.
Ex:
$(".block").animate({"left": "+=50px"}, "slow");
You can use multiple parameters in the brackets like background-color, opacity, etc as you wish to dynamically change the values.
A link for your reference is located at: http://api.jquery.com/animate/
Most javascript animations rely on timer to create the effect of fluid motion. To slide an image across the page, you would set an interval that changed the css position to the right 1px every 5 milliseconds or something of the like. Javascript animation tutorial.
However, animation is most easily accomplished with a library like jquery or many others.

Categories

Resources