I have an object with the name "element". If somebody touches the tablet, I would like to return the x and y coordinates of the touch position relative to the object, i. e. the upper left corner of the object has the coordinates x=0 and y=0.
I know how to implement this on desktops:
$(function() {
$(document).mousedown(function(e) {
var offset = $("#element").offset();
var relativeX = (e.pageX - offset.left);
var relativeY = (e.pageY - offset.top);
alert(relativeX+':'+relativeY);
$(".position").val("afaf");
});
});
So the word "mousedown" should be replaced by "touchstart", I guess. However, it still doesn't work.
How do I change the above code such that it works on tablets with "touchstart" instead of "mousedown"?
UPDATE: See Daniel Lavedonio de Lima's answer below
You have to explicitly pull a touches object out of the event, it doesn't contain the coordinates directly. Look at line two of the code below.
Here is the code I always use to get touch/pointer coordinates:
if(e.type == 'touchstart' || e.type == 'touchmove' || e.type == 'touchend' || e.type == 'touchcancel'){
var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
x = touch.pageX;
y = touch.pageY;
} else if (e.type == 'mousedown' || e.type == 'mouseup' || e.type == 'mousemove' || e.type == 'mouseover'|| e.type=='mouseout' || e.type=='mouseenter' || e.type=='mouseleave') {
x = e.clientX;
y = e.clientY;
}
Put this inside an event listener that listens for any or all of those events and add your offset calculation and this should work.
Christopher Reid's answer almost worked for me, but I had to make a few ajustments because originalEvent property was not part of the event when I was testing in Google Chrome version 81.0.4044.138 and Mozila Firefox version 76.0.1.
Since I found some answers that use directly the event and other that uses event.originalEvent property, I added a check to use the first if the latter is undefined.
So instead of:
var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
I used:
var evt = (typeof e.originalEvent === 'undefined') ? e : e.originalEvent;
var touch = evt.touches[0] || evt.changedTouches[0];
So the full answer then becomes:
if(e.type == 'touchstart' || e.type == 'touchmove' || e.type == 'touchend' || e.type == 'touchcancel'){
var evt = (typeof e.originalEvent === 'undefined') ? e : e.originalEvent;
var touch = evt.touches[0] || evt.changedTouches[0];
x = touch.pageX;
y = touch.pageY;
} else if (e.type == 'mousedown' || e.type == 'mouseup' || e.type == 'mousemove' || e.type == 'mouseover'|| e.type=='mouseout' || e.type=='mouseenter' || e.type=='mouseleave') {
x = e.clientX;
y = e.clientY;
}
Normally you would use e.g. e.touches[0].clientX to handle touch events
A non jquery solution, Assuming you have the following HTML
<div id="touchme" style="width: 200px; height: 200px; background: blue;">
And script
document.getElementById("touchme").addEventListener("touchstart",
function clicked(e) {
var br = document.getElementById("touchme").getBoundingClientRect();
// x & y are relative to the clicked element
var x = e.touches[0].clientX - br.left;
var y = e.touches[0].clientY - br.top;
console.log("x: " + x + " y: " + y);
});
Note the following script handles only the first (of all the possible) touch input
Try this:
$(function(){
$('body').on('touchstart', function(e) {
var offset = $("#element").offset();
var t = e.targetTouches.length > 0 ? e.targetTouches.item(0) : e.touches.item(0);
var relativeX = t.pageX - offset.left;
var relativeY = t.pageY - offset.top;
console.log(relativeX+':'+relativeY);
$(".position").val("afaf");
});
});
PointerEvent supports mouse and touch both.
For example, let's see Sortable.js.
Bind events #L423
el.addEventListener('pointerdown', handler);
Get coords #L574
let touch = (evt.touches && evt.touches[0]) || (evt.pointerType && evt.pointerType === 'touch' && evt);
let clientX = (touch || evt).clientX;
let clientY = (touch || evt).clientY;
I adapted the Domenico solution to move the camera on pc and mobile for threeJS without orbitcontrols:
window.addEventListener("touchmove", function clicked(e) {
cursor.x = e.touches[0].clientX / sizes.width - 0.5
cursor.y = -(e.touches[0].clientY / sizes.height - 0.5)});
In case you have some built-in scroll, you should do it as follows:
const rect = event.target.getBoundingClientRect();
x = event.targetTouches[0].pageX - (rect.left + document.documentElement.scrollLeft);
y = event.targetTouches[0].pageY - (rect.top + document.documentElement.scrollTop);
Related
i'm developing a canvas-based timeline.
I want to trigger the onClick event to get informations about the clicked element.
canvas.onclick = function(e){
var evt = e || event;
var x = evt.offsetX;
var y = evt.offsetY;
for(var i=0;i<items_loaded.length;i++){
var item = items_loaded[i];
alert(x + ' | ' + y);
if((x > item['x_start'] && x < item['x_end']) && (y > item['y_start'] && y < item['y_end'])){
alert('Trovata fermata con ID: ' + item['id']);
}
}
}
I checked the code and the event seems to not fire right.
I want to capture the event when my drop action fails, either because the user did not drop at the right location or may be he himself has cancelled it by hitting 'Esc' key.
Take a look at this script. Took me some time to write and finish it. => DEMO
If this is what you want, let me know.
Note: => this code isn't compatible with legacy (browsers that don't have HTML5 support) browsers (e.g. IE8 etc)
First, we define our draggable element by setting its draggable attribute to true
<div id="draggable" draggable="true"> Drag this div </div>
Then we define our dropzone (target:where the element should be dropped on)
<div class="dropzone" id="dropzone">Dropzone</div>
We need to get the coordinates of the mouse when the element is being released, so we know if the mouse was released on the dropzone or not (I've put an alert notification showing whether the dragend event occurred on the dropzone. If on the dropzone than it will alert dropped on the dropzone, else it will alert dropped not on the dropzone)
function cords(event)
We also need to get the coordinates of the dropzone element, so we will be able to find where the drop event (successful or not (*manually cancelled (Esc) or dropped on the wrong place)) occurred.
var elTop = dragZone.getBoundingClientRect().top + getDocTopLeftPos().fT;
var elLeft = dragZone.getBoundingClientRect().left;
var elBottom = elTop + parseInt(getElProps(dragZone,'height'));
var elRight = elLeft + parseInt(getElProps(dragZone,'width'));
We will know whether the drag operation was successful or not via (on)dragend event
HTML
<div id="draggable" draggable="true">
Drag this div
</div>
<div class="dropzone" id="dropzone">Dropzone</div>
CSS
#draggable {
width: 200px;
height: 50px;
text-align: center;
background: red;
margin-bottom:50px;
}
.dropzone {
width: 200px;
height: 200px;
background: brown;
margin-bottom: 10px;
padding: 10px;
text-align:center
}
Javascript
//checking if the browser is Internet Explorer
var isIEX = navigator.userAgent.match(/Trident/);
var doc = isIEX ? document.documentElement : document.body;
function getDocTopLeftPos() {
scrollTop = window.pageYOffset || doc.scrollTop;
scrollLeft = window.pageXOffset || doc.scrollLeft;
clientTop = doc.clientTop || 0;
clientLeft = doc.clientLeft || 0;
fromTop = Math.round(scrollTop - clientTop);
fromLeft = Math.round(scrollLeft - clientLeft);
return {fT:fromTop, fL:fromLeft}
}
//get the value of the property of the specified element
function getElProps(el,attr){
whaT_ = isIEX ? el.currentStyle : window.getComputedStyle(el);
getWhaT_ = isIEX ? whaT_.getAttribute(attr) : whaT_.getPropertyValue(attr);
return getWhaT_;
}
//getting the coordinates of the mouse
function cords(ev) {
if (ev.pageX == null && ev.clientX != null ) {
var html = document.documentElement;
var body = document.body;
ev.pageX = ev.clientX + (html && html.scrollLeft || body && body.scrollLeft || 0) - (html.clientLeft || 0)
ev.pageY = ev.clientY + (html && html.scrollTop || body && body.scrollTop || 0) - (html.clientTop || 0)
}
return {x:ev.pageX,y:ev.pageY}
}
var x,y;
var dragZone = document.getElementById("dropzone");
//getting our element's coordinates
//the mouse should be between these coordinates, otherwise that wouldn't be the dropzone
//from top
var elTop = dragZone.getBoundingClientRect().top + getDocTopLeftPos().fT;
//from left
var elLeft = dragZone.getBoundingClientRect().left;
//the height of the draggable element + its top coordinate
var elBottom = elTop + parseInt(getElProps(dragZone,'height'));
//the width of the draggable element + its left coordinate
var elRight = elLeft + parseInt(getElProps(dragZone,'width'));
var dragElement;
document.getElementById("draggable").addEventListener("dragstart",function(event){
evt = event || window.event;
if(navigator.userAgent.match(/Firefox/)) event.dataTransfer.setData('text/plain',null)
},false);
document.addEventListener("dragstart",function(event){
evt = event || window.event;
//the element that is being dragged
dragElement = evt.target || evt.srcElement
//make our target half transparent;
dragElement.style.opacity = 0.5;
},false);
document.addEventListener("dragend",function(event){
console.log(x + ' ' + y + ' ' + elTop + ' ' + elLeft + ' ' + elBottom + ' ' + elRight);
//if the dragged element was dropped at the right place
if(x>elLeft && x<elRight && y>elTop && y<elBottom){
alert('dropped on the dropzone');
}else{
//if the destination was wrong or the drag was cancelled (Esc)
alert('dropped not on the dropzone')
}
//reset our element's transparency
dragElement.style.opacity = 1;
dragZone.style.background = "brown";
},false);
document.addEventListener("dragover",function(event){
evt = event || window.event;
x = cords(evt).x;
y = cords(evt).y;
console.log(x + ' ' + y);
//this will prevent browser's default behaviour which will allow the drop event to occur
if(evt.preventDefault) evt.preventDefault() ; else return false;
},false);
document.addEventListener("dragenter",function(event){
evt = event || window.event;
dropTarget = evt.target || evt.srcElement;
//this will highlight potential drop target when the draggable element enters it
if(dropTarget.className == "dropzone" ){
dropTarget.style.background = "purple";
}
}, false);
document.addEventListener("drop",function(event){
evt = event || window.event;
if(evt.preventDefault) evt.preventDefault() ; else return false;
}, false);
I'm trying to get a page to have cross browser support, however I keep getting stuck on Mozilla Firefox. I have IE and Chrome working though. The code is:
function positiontip(e){
var e = window.event ? event : e;
if (enabletip) {
var curX;
var curY;
if (e.pageX || e.pageY) {
curX = e.pageX;
curY = e.pageY;
} else if (e.clientX || e.clientY) {
curX = e.clientX + document.body.scrollLeft
+ document.documentElement.scrollLeft;
curY = e.clientY + document.body.scrollTop
+ document.documentElement.scrollTop;
}
When ever I try to use the code, Firefox console spits out an error that
e is undefined "if (e.pageX || e.pageY) {"
I have tried calling the function via
positiontip();
and
positiontip(event);
But neither are working.
any ideas?
Try replacing var e = window.event ? event : e; with e = e || window.event;
Nevermind. The problem was that the function positiontip() was called in another function and the other function was being passed the event. I had to changed the html to pass the event to showtooltip() [the upper function] that then passed the event to positiontip().
I have code to get x-y coordinates when the browser scrolls:
left1 = window.event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
top1 = window.event.clientY + document.body.scrollTop + document.documentElement.scrollTop;
This is working in IE7, but not in Mozilla Firefox 3.5.19. How can I get it working in Firefox?
The following JS works in IE 8 and firefox 3.6.17
function getScrollingPosition()
{
var position = [0, 0];
if (typeof window.pageYOffset != 'undefined')
{
position = [
window.pageXOffset,
window.pageYOffset
];
}
else if (typeof document.documentElement.scrollTop
!= 'undefined' && document.documentElement.scrollTop > 0)
{
position = [
document.documentElement.scrollLeft,
document.documentElement.scrollTop
];
}
else if (typeof document.body.scrollTop != 'undefined')
{
position = [
document.body.scrollLeft,
document.body.scrollTop
];
}
return position;
}
This article also may help.
http://www.softcomplex.com/docs/get_window_size_and_scrollbar_position.html
Remember that the click event is handled differently in Mozilla than it is in internet explorer. Also they hold different ways of attaining the position of the cursor location. This is a very easy google search to get the specifics on either.
var IE = document.all ? true : false; // check to see if you're using IE
if (IE) //do if internet explorer
{
cursorX = event.clientX + document.body.scrollLeft;
cursorY = event.clientY + document.body.scrollTop;
}
else //do for all other browsers
{
cursorX = (window.Event) ? e.pageX : event.clientX + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft);
cursorY = (window.Event) ? e.pageY : event.clientY + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop);
}
Also note that you should have something like the following in your initialization code:
if (window.Event) {
if (window.captureEvents) { //doesn't run if IE
document.captureEvents(Event.MOUSEMOVE);
}
}
document.onmousemove = refreshCursorXY;
On the click side of things as I said there is differences in what value the click is attributed between browsers. For example, this check should happen in your click event (that you send e, the event, to). e will not be sent by I.E. so we do it like so:
//internet explorer doesn't pass object event, so check it...
if (e == null)
{
e = window.event;
}
//1 = internet explorer || 0 = firefox
if ((e.button == 1 && window.event != null || e.button == 0))
And again, there are many differences between IE and other browsers, thus there is much documentation. Google searches can do wonders if you require further information on the subject.
Only IE puts the event information in the global window object. All other browsers follow the W3C recommendation that event information be passed to the listener callback registered on an element. You will also need to use element.addEventListener() instead of element.attachEvent(). See the addEventListener() documentation on the Mozilla Developer Network.
IE6 is getting to be pain but it still makes up (apparently) a good chunk of the browser market share, so I need to make this work.
function getPosition(e)
{
e = e || window.event;
var cursor = {x:0, y:0};
if (e.pageX || e.pageY)
{
cursor.x = e.pageX;
cursor.y = e.pageY;
}
else
{
var dex = document.documentElement;
var b = document.body;
cursor.x = e.clientX + (dex.scrollLeft || b.scrollLeft) - (dex.clientLeft || 0);
cursor.y = e.clientY + (dex.scrollTop || b.scrollTop) - (dex.clientTop || 0);
}
return cursor;
}
function outCursor(e){
var curPos = getPosition(e);
alert(curPos);
}
window.captureEvents(Event.MOUSEMOVE);
window.onmousemove = outCursor;
IE is complaining about the Event in window.captureEvents(Event.MOUSEMOVE);
'Event' is undefined.
I think ie6 doesn't supports captureEvents. So try
if (window.captureEvents) {
window.captureEvents(Event.MOUSEMOVE);
}
Try running the script without window.captureEvents(Event.MOUSEMOVE);. I don't think it is necessary. Also, like someone mentioned change the window.onmousemove to document.onmousemove
Also here is a good resource on writing this kind of script http://www.quirksmode.org/js/events_properties.html#position