How to update X and Y coordinate when hovering an object - javascript

I have an image that changes position when I click inside a div like this:
mainDiv.click(function (e) {
var mouseX = e.clientX,
mouseY = e.clientY;
test2 = Math.atan(mouseY/mouseX);
test3 = ((test2 * 180) / 3.14);
$("#hgun").rotate(test3);
});
But it only changes position when I click inside the div. How can I make it change position when I hover inside the div ?

The .hover() method binds handlers for both mouseenter and mouseleave events. You can use it to simply apply behavior to an element during the time the mouse is within the element.
It is called like this:
$(selector).hover(handlerIn, handlerOut)
Which is short for:
$(selector).mouseenter(handlerIn).mouseleave(handlerOut);
In your case that would be:
mainDiv.hover(function (e) {
var mouseX = e.clientX,
mouseY = e.clientY;
test2 = Math.atan(mouseY / mouseX);
test3 = ((test2 * 180) / 3.14);
$("#hgun").rotate(test3);
},
function (e) {
//On mouseleave
});
Further read: jQuery hover documentation, jQuery mouse events
Update, based on author's comment:
I am not sure what exactly you are trying to achieve, but if you want your calculation and the related actions to be made every time the mouse moves within the container, you can use the mousemove event.
I've done a simple Fiddle based on your code, check it out: http://jsfiddle.net/sQ4Z4/1/
I used the first jQuery Rotate Plugin I found, which might not be the one you used, but it should be enough to get you in the right direction.
Basically your code should look something like this:
mainDiv.mousemove(function (e) {
var mouseX = e.clientX,
mouseY = e.clientY;
test2 = Math.atan(mouseY / mouseX);
test3 = ((test2 * 180) / 3.14);
$("#hgun").rotate(test3);
});

Change this line:
mainDiv.click(function (e) {
to
mainDiv.hover(function (e) {
hover accepts two functions: The first is executed on mouseenter, the second on mouseleave.

Related

Getting currently clicked co-ordinates relative to an element

i have a function to get the co-ordinates of the recently clicked position with respect to a div element without using JQuery which is working fine .
without jquery (working) :
var Board = document.getElementById("board"); // div element
function mouseListener(e)
{
var posX = e.clientX - Board.getBoundingClientRect().left,
posY = e.clientY - Board.getBoundingClientRect().top
console.log(posX+" : "+posY);
}
window.addEventListener("mousedown", mouseListener,false);
But this one uses JQuery and giving different co-ordinates as compared to the previous code
using jquery(not working) :
var Board = $("#board");
function mouseListener(e)
{
var posX = e.clientX - Number(Board.css("left").replace("px", "")),
posY = e.clientY - Number(Board.css("top").replace("px", ""));
console.log(posX+" : "+posY);
}
$(window).mousedown(mouseListener);
How to write this properly on jQuery so that it'll work like the first code?
With jQuery you have to use .offset() to get the same values as with .getBoundingClientRect():
function mouseListener(e) {
var posX = e.clientX - parseFloat(Board.offset().left),
posY = e.clientY - parseFloat(Board.offset().top);
console.log(posX+" : "+posY);
}
jQuery.fn.offset() Reference here;
There are three ways to attach the event-handler. Used in jQuery < 1.7 but still working in newer versions:
$(window).bind('mousedown', mouseListener);
As of jQuery 1.7 method .on() is used, it has the greatest flexibility also for event delegation:
$(window).on('mousedown', mouseListener);
The third is what you have used, it's only a shortcut and calls internally .on().
Reference jQuery.fn.bind() - - - - Reference jQuery.fn.on()
Whatever you have done is absolutely correct logicwise, just minor syntactical mistakes.
var Board = $("#board");
function mouseListener(e)
{
var posX = e.clientX - Number(Board.css("left").replace("px", "")), //you forgot to put closing braces here and in the next line.
posY = e.clientY - Number(Board.css("top").replace("px", ""));
console.log(posX+" : "+posY);
}
$(window).mousedown(mouseListener);
Make sure you have used style left and top in the element with id "#board" else output will be NaN : NaN.

without jquery i need to find out if the mouse is over an element, not determine when it becomes over (in case it doesn't move to trigger onmouseover)

without jquery
basically what I am looking for is the ability to see if the mouse is over a div when a countdown finishes
if the user is over the div then perform action for that div
onmouseover only triggers when the mouse crosses the threshold of the div, if the mouse hasn't moved it wouldn't trigger, so that wouldn't work
I need to determine if the mouse is currently over a div at a specific point in time, if it has moved or not from the starting point
all of my hunting has only found onmousover, and nothing to see if the mouse just happens to be there to begin with
I don't have the javascript skills to determine overall coords of div, then map mouse coords and see if it fits there... which is what I believe I need to do
After reading the second answer (the one with millions of a elements) on this SO question, I've came up with this method works without moving the mouse on page load, without involving millions of elements.
HTML
<div id=t></div>
CSS
#t {
/* for illustrative purposes */
width: 10em;
height: 5em;
background-color: #0af;
}
#t:hover {
border-top-style: hidden;
}
JavaScript
document.addEventListener('click', function () {
var c = window.getComputedStyle(document.getElementById('t')).getPropertyValue('border-top-style');
if (c === 'hidden') {
alert('Mouse in box');
} else {
alert('Mouse not in box');
}
}, false);
As stated earlier, bind to the finish event of your countdown instead of the click event on the document.
You may also use any CSS style that's changed on :hover, I chose border-top-style as it is conspicuous. If you're using a border, choose something else.
Here's a jsFiddle.
set a flag to true onmouseover and to false onmouseleave. when countdown finishes if flag is true then it is over element.
HTML
<div id="div-name">the section of the code i am working with has a countdown timer, when it reaches 0 i need to know if the mouse is over a specific box</div>
<button id="notification" onclick="javascript: letsCountIt(5);">click to start countdown</button>
JS
window.ev = false;
document.getElementById('div-name').onmouseover = function () {
window.ev = true;
console.log(window.ev);
}
document.getElementById('div-name').onmouseout = function () {
window.ev = false;
console.log(window.ev);
}
window.letsCountIt = function (cdtimer) {
cdtimer--;
document.getElementById('notification').innerHTML = cdtimer;
if (cdtimer == 0) {
if (window.ev === true) {
alert('over');
} else {
alert('not over');
}
} else {
setTimeout(function(){letsCountIt(cdtimer);}, 1000);
}
}
Look into document.elementFromPoint . When you pass an x,y to elementFromPoint, it will return whatever element (or <body>, if no other specific element) is at that point. You can easily check if this element is the element you want.
The problem then is finding out what point your mouse is at. How to get the mouse position without events (without moving the mouse)? seems to say - don't. At least use mouseMove to track the cursor. The linked question gives examples of how to do so. (Look to the lower scoring answers, as the higher ones only got points for being snarky.)
Just want to say that, I think jQuery's mouseenter and mouseleave events would make this a lot easier, but if you can't use them, maybe this will help you.
Depending on how your page is laid out, this may not be too difficult. You can get the position of your element using the following. Quoting from another answer
element.offsetLeft and element.offsetTop are the pure javascript
properties for finding an element's position with respect to its
offsetParent; being the nearest parent element with a position of
relative or absolute
So, if your element is positioned relatively to the body, so far so good (We don't need to adjust anything).
Now, if we attach an event to the document mousemove event, we can get the current coordinates of the mouse:
document.addEventListener('mousemove', function (e) {
var x = e.clientX;
var y = e.clientY;
}, false);
Now we just need to determine if the mouse falls within the element. To do that we need the height and width of the element. Quoting from another answer
You should use the .offsetWidth and .offsetHeight properties. Note
they belong to the element, not .style.
For example:
var element = document.getElementById('element');
var height = element.offsetHeight;
var width = element.offsetWidth;
Now we have all the information we need, and just need to determine if the mouse falls within the element. We might use something like this:
var onmove = function(e) {
var minX = element.offsetLeft;
var maxX = minX + element.offsetWidth;
var minY = element.offsetTop;
var maxY = minY + element.offsetHeight;
if(e.clientX >= minX && e.clientX <= maxX)
//good horizontally
if(e.clientY >= minY && e.clientY <= maxY)
//good vertically
}
This code works, but the mouse has to be moved once after page load.
var coords;
var getMouseCoordinates = function (e) {
'use strict';
return {
x: e.clientX,
y: e.clientY
};
};
document.addEventListener('mousemove', function (e) {
coords = getMouseCoordinates(e);
}, false);
document.addEventListener('click', function () {
var divCoords = document.getElementById('t').getBoundingClientRect();
if (coords.x >= divCoords.left && coords.x <= divCoords.right && coords.y >= divCoords.top && coords.y <= divCoords.bottom) {
alert('Mouse in box');
} else {
alert('Mouse not in box');
}
}, false);
You wouldn't bind to the click event of document, but rather the finish event of your countdown.
Here's an example. Try clicking in the output window.
You don't need any coordinates or mouse events, if you know a selector for that element:
if (document.querySelector('#elementSelector:hover')) {
alert('I like it when you touch me!');
}

in gamequery I am trying to move a selected object with mousetracker by clicking on the object, and dragging it

I know I can use mousedown selection for it, but I am wanting the clicked on sprite to follow my mouse, there is a mousetracker function of sorts mentioned in the api; but unfortunately there are no examples of this other than stating that it allows mouse detection.
//add mousedown events for yarnballs.
$(".gQ_sprite").mousedown(function() {
clickedDivId = $(this).attr('id');
if(clickedDivId.charAt(8) == "-")
{
currentClickedDivId = clickedDivId
$(document).mousemove(function(e){
spriteXPosition = e.pageX
spriteYPosition = e.pageY
});
}
});
I have the location of the mouse selected, just not sure how to get the selected sprite to follow it.
any help would be greatly appreciated.
What Mati said is correct: $.gQ.mouseTracker allows you to access the mouse's state outside of an event handler. The example he gives is correct but it can't be used to move a gQ object (sprite, tile-map or group) around because you'r not allowed to use the .css() function for those. Doing so will break collision detection.
If what you want is to move a gQ object you should do this instead :
$('#' + currentClickedDivId).xy($.gQ.mouseTracker.x, $.gQ.mouseTracker.y);
But since this should be done in a periodical callback, the smoothness of the dragging will depend on the refresh rate.
If you want to use event handlers instead you could modify you code to look like this (without using the mouseTracker):
var clickedDiv;
var clickedDivOffset = {x:0, y:0};
$(".gQ_sprite").mousedown(function(e) {
clickedDiv = $(this);
clickedDivOffset = {
x: e.pageX - clickedDiv.x() - $().playground().offset().left,
y: e.pageY - clickedDiv.y() - $().playground().offset().top
};
});
$(".gQ_sprite").mouseup(function() {
clickedDiv = false;
});
$().playground().mousemove(function(e) {
if(clickedDiv){
clickedDiv.xy(
e.pageX - clickedDivOffset.x,
e.pageY - clickedDivOffset.y,
);
}
});
This will implement a drag-n-drop effect. If you want the clicked element to stick to the mouse you will have to slightly adapt the code but the basics will remain the same.
According to the documentation:
If the mouse tracker is enabled you can check the state of the mouse at anytime by looking into the object $.gQ.mouseTracker where x and y contain the position of the mouse and 1, 2 and 3 a boolean value where true means that the first, second or thrid button is pressed.
Observe the output of:
$("#playground").playground({ refreshRate: 60, mouseTracker: true });
$.playground().startGame();
$.playground().registerCallback(function(){
console.log( $.gQ.mouseTracker );
}, 1000);
To make those divs actually follow the cursor, you have to use .css()
$('#' + currentClickedDivId).css({
top: $.gQ.mouseTracker.y + 'px',
left: $.gQ.mouseTracker.x + 'px'
});

Get clicked element by a trigger

Is there any way how to get element selector which was clicked by trigger? I'm trying to avoid specification of certain element in trigger method like $("#certain_element").trigger(e); I want to call a trigger on some position in the page defined by pageX and pageY params and then get an element which was clicked.
var e = new jQuery.Event("click");
e.pageX = 80;
e.pageY = 40;
$('*').trigger(e);
$('*').click(function() {
alert('This element was clicked:'+$(this).get(0).tagName);
});
This script isn't working correctly.
Based on the comments from Andrew and Anurag:
$(document.elementFromPoint(80, 40))
.trigger('click')
.css('background-color', 'blue');
You are triggering it BEFORE binding the click.
var e = new jQuery.Event("click");
e.pageX = 80;
e.pageY = 40;
// binds
$('*').click(function() {
alert('This element was clicked:'+$(this).get(0).tagName);
});
// then triggers
$('*').trigger(e);
Eventhough, if I were you, I'd use another selector, which would not trigger the event for window, document and another unecessary tags.
$(documnet.body).find('*').click(...);
$(document.body).find('*').trigger(e);

In jQuery, is there a way to manually propagate an event onto a DOM object?

I know the mouseenter is coded such that it propagates mouseover to all the elements within the DOM that it is bound to.
So, like the question states, is there a way to manually apply this propagation to other elements that are separate from the DOM, which I bound the mouseenter event to.
The function, $.stopPropagation(), stops the propagation but is there an applyPropagationTo like function?
Here is the scenario:
Say I have a div, class=divCON. I have a absolute positioned div appended to the body, called divHOV, which is hid. When I mouseenter divCON, divHOV becomes visible and follows my mouse when I am within divCON.
I want it so that when my mouse is moving within divCON, the mouse tends to enter divHOV if the browser is slow to reposition the divHOV while moving the mouse. I want it so that I can propagate divHOV's mouseenter onto divCON so that a mouseleave event is not trigger when I go on divHOV.
jsFiddle: http://jsfiddle.net/vuxcR/
Note how when the mouse enters divHOV, it mouseleaves the divCON. I want it so that when it does not mouseleave divCON when I enter divHOV.
Fiddle: http://jsfiddle.net/vuxcR/1/
Here's the desired code. See the comments and bottom for explanation:
$(document).ready(function() {
var $divCON = $(".divCON");
$divCON.bind("mouseenter", function() {
//Cancel if this function has already run (so, if the next element
// has class divHOV
if($(this).next().hasClass('divHOV')) return;
$divHOV = $("<div class='divHOV'></div>");
$divHOV.mousemove(function(ev){
var offset = $divCON.offset();
var height = $divCON.height();
var width = $divCON.width();
var left = offset.left;
var top = offset.top;
var bottom = top + height;
var right = left + width;
// If the mouse coordinates are within the box
if(ev.pageX >= left && ev.pageX <= right &&
ev.pageY >= top && ev.pageY <= bottom){
//Trigger move.
$divHOV.css({'top': ev.pageY - 3 + 'px', 'left': ev.pageX + 3 + 'px'});
}
});
$(this).after($divHOV);
});
$divCON.bind("mousemove",function(e) {
$(".divHOV").css({'top': e.pageY - 3 + 'px', 'left': e.pageX + 3 + 'px'});
});
});
When the user enters .divCON for the first time, .divHOV is added. When moving the mouse (see bottom), divHOV is positioned again. Once the mouse enters .divHOV, the coordinates are calculated again IF the mouse is within the box of divCON.
When the mouse enters .divCON again, the function immediately returns, because .divHOV already exists: if($(this).next().hasClass('divHOV')) return;.

Categories

Resources