Getting currently clicked co-ordinates relative to an element - javascript

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.

Related

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'
});

How to update X and Y coordinate when hovering an object

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.

Apply jQuery events to all class elements?

I have the following code which will allowed a user running iOS to move a <div> with the class .drag around on the page. This works fine when there is one istance of .drag, but fails to work when there are two instances of it. Is it possible to have the code find all of the <div>'s, then allow them to be draggable?
var drag = $(".drag")[0];
xPos = drag.offsetWidth / 2;
yPos = drag.offsetHeight / 2;
drag.addEventListener("touchmove", function() {
event.preventDefault();
$(this).css({
'left' : event.targetTouches[0].pageX - xPos + 'px',
'top' : event.targetTouches[0].pageY - yPos + 'px'
});
});
When you use $(selector)[0], you get the first DOM element that matches the selector. Use .each() instead to add the event listener to all elements that match the selector:
$(".drag").each(function () {
var drag = this;
xPos = drag.offsetWidth / 2;
yPos = drag.offsetHeight / 2;
drag.addEventListener("touchmove", function() {
event.preventDefault();
$(this).css({
'left' : event.targetTouches[0].pageX - xPos + 'px',
'top' : event.targetTouches[0].pageY - yPos + 'px'
});
});
});​
Yes, it's possible. But you are using a jQuery selector (which can select and return multiple elements) and then immediately unwrapping it to return the first element. You can modify your code to use jQuery functions throughout and avoid this.
// an array of all elements with class "drag"
// each element is wrapped
var drag = $(".drag");
// selects all matching elements, but then references
// the first raw DOM element in the array
var drag = $(".drag")[0];
Another way of looking at it:
var matches = $(".drag");
// each() executes a function for each matched element
matches.each(function () {
var drag = this; // raw dom element
// or, wrap to get jQuery object
// var drag = $(this);
});​
As I mentioned, you can also use jQuery functions throughout your code. Two quick examples I see are the x/y coordinate calculation and the event binding.
First, you declare that you want only the first element by using [0].
Second, you should use jQuery's on() method. Here's how I see you function:
var drag = $(".drag");
drag.on("touchmove", function(event) {
xPos = $(this).offsetWidth / 2;
yPos = $(this).offsetHeight / 2;
event.preventDefault(); // preventDefault is IE-specific, is it?
$(this).css({
'left' : event.targetTouches[0].pageX - xPos + 'px',
'top' : event.targetTouches[0].pageY - yPos + 'px'
});
});
This is probably obvious to most experienced devs, but could be helpful to some junior devs who like myself have had trouble getting jQuery to apply to multiple elements.
Today I learned that you have to make sure you’re loading your script outside the div itself.
I was mistakenly loading the script inside the first element, and wondering why the jQuery function wasn’t applying to the other div farther down the page.
Screenshot showing < script > inside parent < div >
^ I was doing it wrong

Get accurate position for a click on a linked image using jquery

I'm working on an app that allows tagging directly on photos via clicking (like Facebook, flickr, et al). However, I can't seem to register the right coordinates for a click on a photo. The problem is the x coordinates seem to be absolute x distance of a click within the browser window(rather than within the photo), while the y coordinates are often negative or incredibly small (negative near the top, small near the bottom). These are the values I get when clicking near the top left corner (which should register as being at or near 0: "x"=>"219", "y"=>"-311"... 219 seems about right when measuring the distance from the left side of the browser window, but the distance should be within the photo area)
I'm currently capturing click events and coordinates on a photo using a regular link (the link contains other relevant photo data) and doing the math (same calculations used in the jquery docs) before passing it along to my rails app. I doubt the method has much to do with the erroneous values, though I suspect the math or some css quirk could be at fault. In either case, I'm absolutely boggled.
JS:
$(document).ready(function(){
clickTag();
});
function clickTag(){
$("#taggable").click(function(e){
var x = e.pageX - this.offsetLeft;
var y = e.pageY - this.offsetTop;
var url = $(this).attr("href");
courl = url + '&x=' + x + '&y=' + y;
$.ajax({
type:"GET",
url: courl,
dataType:"script"
});
return false;
});
}
CSS:
`<div class="content">
<div id="image_container" style="position:relative;width:405px;float:left;height:600px;>
<img alt="taggable_image" src="taggable_image.jpg" />
<div class="tags" id="tags"></div>
</div>
</div>`
for your x and y try using this:
var x = e.pageX - $(this).offset().left;
var y = e.pageY - $(this).offset().top;
let me know if that doesn't work
EDIT: to clarify - you are getting the left and top offset from the dom element directly. the reason i suggest you use the jQuery offset() function is that jQuery is more likely to calculate the correct position cross browser.
EDIT 2: Can you please try to assign the click event to the image as opposed to the link. I have a sneaking suspicion that the link is reporting its top offset as the bottom of the element it encapsulates...
My function is:
function getCoords(target, event)
{
var $target = $(target);
var offset = $target.offset();
var bordersize = $target.attr('border');
return {
x: (event.pageX - offset.left - bordersize) | 0,
y: (event.pageY - offset.top - bordersize) | 0
}
}
call:
$("#image").on('click', function(event){
var coords = getCoords(this, event);
console.log('X: ', coords.x);
console.log('Y: ', coords.y);
});
Note: used fast float2int.

event.pageX - Use jQuery Event in a function not bound through jQuery?

I have a table, and when the user clicks on each cell, some details should appear in a small popup div that appears where the user clicked. I'm using jQuery, but not to bind the function to the onClick event.
function detailPopup(cell, event, groupName, groupID, ...)
{
var newDiv = document.createElement("div");
newDiv.id = "detailPop" + groupID;
newDiv.className = "priceDetailPopup";
newDiv.innerHTML = "<p>" + groupName + "</p>"; // more will go here
$(newDiv).click(function()
{
$(this).fadeOut("fast").remove();
}
);
$("#main").append(newDiv);
$(newDiv).css({"left" : event.pageX, "top" : event.pageY}).fadeIn("fast");
}
Everything is working wonderfully in FF, Safari, and Chrome. In IE, it all works except that the detail div appears below the table. event.pageX/Y aren't working. I know jQuery will fix those for IE if I bind the function through jQuery like this:
$(cell).click(function(e) { ... e.pageX ... })
But I can't do that. (I don't think I can - if you do, please explain how I can get six variables into that function without having to use non-xhtml tags in the cell.)
Is there a way to have jQuery "fix" the event object without binding the function through jQuery? $JQuery.fixEvent(event); or something? I can't find any reference to doing so on their site.
e = jQuery.event.fix(e); //you should rename your event parameter to "e"
I found the fix function by searching through the jQuery source code.
Alternatively, you could use this to get the mouse coordinates without jQuery...
var posx = 0;
var posy = 0;
if (!e) var e = window.event;
if (e.pageX || e.pageY) {
posx = e.pageX;
posy = e.pageY;
}
else if (e.clientX || e.clientY) {
posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
Via PPK: http://www.quirksmode.org/js/events_properties.html
This blog post seems to be relevant: http://www.barneyb.com/barneyblog/2009/04/10/jquery-bind-data/
Seems it's just jQuery("#selector").bind("click", {name: "barney"}, clickHandler);, then e.data.name to access it in the event.
You might find that the issue you're facing is not a positioning issue at all. Based on the syntax you posted, you may be experiencing an IE bug relating to the use of the CSS ID selector.
$("#main").append(newDiv);
If IE doesn't recognize the "#main" element, the append() function will not work correctly. IE (pre-v7) has spotty support for the ID (#) selector. Instead try:
$('div[id="main"]').append(newDiv);
Try this and let me know how it works for you.

Categories

Resources