I have an one page app in Meteor.
I want to track when whether a bookmarklet (in the form of a <a> tag containing an image) has been dragged towards the bookmarks bar.
I'm using a combination of mousedown, mousemove, and mouseup to try to track the drag.
Template.myTemplate.events = {
'mousedown': function(){
Session.set('dragging', true)
console.log('drag starts')
},
'mouseup': function(){
if (Session.get('dragging') == true && event.y < 10){
// The result i want
}
Session.set('dragging', false)
console.log('drag stops')
}
}
The drag starts well enough, but soon after the mouse leaves the <a> tag it just seems to baulk, and mouseup doesn't register as it should.
The logic works as it should if I return false after mouseup and mousedown - ie. I can move the mouse far and wide after mousedown, and watch for event.y being < 10 and there's no baulk - but then the code does not have the desired effect of the user being able to drag the <a> tag.
Do you have any ideas?
'mousedown': function(){
You're doing mousedown on the template, it should be on the a element.
So, do this instead:
'mousedown a': function(){
Or choose the right a element here.
sorry for the delay, but i could only see now kk
But you can get your event data from the bank with mousedown (I believe you already do that), and add the mousemove where you want to drop your event. It's not quite the right way to implement it, but it can solve
Related
I'm building a dragging widget thingy, it listens to 'mouseup'/'mousedown' events from the interactive element.
Works fine most of the time but I've found the 'mouseup' to be a bit unreliable. Is there an event independent way of checking whether the mouse buttons are up/down? I could attach it to a timer or the mousemove event to make it foolproof.
You have to use an event however you can have script from within the events to assign the state of the mouse down that you can test later.
var isMouseDown = false;
document.addEventListener("mousedown", function()
{
isMouseDown = true;
});
document.addEventListener("mouseup", function()
{
isMouseDown = false;
});
if (isMouseDown == true) { ... }
Is there an event independent way of checking whether the mouse buttons are up/down?
No, there isn't. But for your dragging code, your best bet for listening for mouseup isn't the element you're dragging, but the document as a whole. You still won't get the event if the mouse release is outside the window, but you will if the mouse has been moved abruptly and released such that it's outside your element when the release occurs.
You can also listen for mousemove, which of course fires a lot, and also tells you whether buttons are down (via the buttons property on the event object).
I have created a canvas and I have added mouse events to it:
canvas = document.getElementById('canvas');
context = canvas.getContext('2d');
canvas.width = screenWidth;
canvas.height = screenHeight;
...
// CALLED AT START:
function setup() {
// Mouse movement:
document.onmousemove = function(e) {
e.preventDefault();
target.x = e.pageX;
target.y = e.pageY;
angle = Math.atan2((target.y - localPlayer.getY()),
(target.x - localPlayer.getX()));
// Distance to mouse Check:
var dist = Math.sqrt((localPlayer.getX() - target.x)
* (localPlayer.getX() - target.x) + (localPlayer.getY() - target.y)
* (localPlayer.getY() - target.y));
var speedMult = dist / (canvas.height / 4);
socket.emit("update", {
...
});
}
document.onmousedown = function(e) {
e.preventDefault();
}
}
Now the issue is when I hold down the only left mouse button and move the mouse at the same time, my game lags a lot. Simply moving the mouse causes no lag. I have tested this on chrome and on firefox. It seems that I can only recreate the issue on chrome. Using the middle mouse button or right button has the same behaviour in the game and cause no lag. Only when using the left mouse button causes lag.
I have looked around for answers and found that I should prevent default behaviour like so:
e.preventDefault();
But that did not resolve the issue. I have also tried to update a number on the screen that represents the mouse position. And it updated normally. Only the game itself was lagging. Could it be that the onMouseMoved is never called whilst the left button is held down? But then why is it called with the middle and right button?
The issue should be with the code I a calling inside of the move method, because it works fine when I am not holding down the left key, and it works well on firefox. There must be something else going on.
EDIT: I decided to a recording on chrome to see what is going on. Here is the result:
What's really odd, when I press the middle mouse button or the right button, the game does the same thing, but it does not lag at all. What are you doing chrome?
EDIT: Test it out here: www.vertix.io note that not everyone seems to be able to reproduce this issue.
Thank you for your time.
When you hold down the left mouse button and move it in the same time, you are dragging.
Edit: In some versions of Chrome, there is a bug (when I posted this answer I had it, now I don't), which causing the drag events to be fired even without the element having the draggable attribute. Normally, drag events should only be fierd from elements which have the draggable attribute set to true (except images and anchors who are drragable by default).
According to the MDN, when drag events are being fired, mouse events, such as mousemove, are not, which means that your function isn't being called.
A possible solution are to use the same function for both drag and mousemove events:
function mouseMove(e) {
//do your things here
...
}
document.addEventListener('mousemove', mouseMove);
document.addEventListener('drag', mouseMove);
Note: If you'll use the same function for both events, you should be aware of which properties of the event you're using in the function, because of the difference between the drag and mousemove events. The two events doesn't contains the exact same properties and the behavior of some properties may not be the same in both of them.
Have you considered throttling?
Check out https://blog.toggl.com/2013/02/increasing-perceived-performance-with-_throttle/
You have the mouse event on the document. As we can not see what you have on the document it is hard to know if that is a cause of your problems.
Try moving the mouse event to the canvas only, as that is the only place you need it I presume. No point handling events for the document if its not part of the game, plus document is last on the list if child elements have events attached. They go first and then it bubbles up to yours.
As it looks like you are using a framework of some type there is in all possibility another mouse event listener that is part of the frame work that may be slowing you down by not preventing default. You will have to search the framework to see if it has a listener for any of the mouse events.
And use addEventListener rather than directly attaching the event via .onmousedown = eventHandler
eg canvas.addEventListener("mousedown",eventHandler);
And add the event listener to the element you need it for, not the document.
function mouseMove(e) {
//do your things here
...
}
document.onmousemove = mouseMove;
document.ondrag = function(e) {
mouseMove(e);
//do another things
...
}
http://jsfiddle.net/63Y54/2/
In the example above when the user clicks and drags left or right off the canvas while holding the mouse button down and then takes their finger off the mouse the oscillator note hangs. I want to fix this. I am curious if their is a simple way to do something like..
if (mouseup == !htmlElement){
then....
}
In this case the html element would be the canvas element as that is what the user is clicking on.
As an attempt to fix this I made the body element encompass the page by setting its CSS width and height to 100%.
I then created a function that selected the body element with a mouseup click handler that launches the oscillator.stop() method. This only works when the user moved their mouse to the side of the page but when they moved down it still creates a hanging note.
This pseudo solution is here:
http://jsfiddle.net/63Y54/5/
I think this similar question answers yours.
jQuery detect mousedown inside an element and then mouseup outside the element
Here is the code from it from a guy named Mike:
var isDown = false;
$("#element").mousedown(function(){
isDown = true;
});
$(document).mouseup(function(){
if(isDown){
//do something
isDown = false;
}
There is additional code handling fringe cases in thelink as well.
I dynamically add this
$(ele).on("mouseover")
when user has mouse over the element, but it seems that mouseover event triggers only when I reenter element.
Here is example in jsFiddle (Click on <div> to add event listener)
How can I achieve this without manually triggering .mouseover() ?
Best solution I came up with was (Thanks to Brandon's suggestion):
Store x,y pos in document (drops performance on webpage a bit):
$(document).mousemove(function (e) {
// Set global values
window.mouseXPos = e.pageX;
window.mouseYPos = e.pageY;
});
And then when animation is finished:
$(document.elementFromPoint(window.mouseXPos, window.mouseYPos)).trigger("mouseenter");
You can't. mouseover only triggers when the mouse crosses the boundary of the element. Once the mouse is within the element, it won't trigger. Your question suggests you might need to take a step back and re-examine your problem. If you are taking action when the mouse is already within the element then why do you need a mouseover event?
You can manually trigger a mouseover with the trigger jQuery function after attaching you eventhandler this way
$(".test").on("click",function(){
$(this).on("mouseover",function(){
alert("");
});
$(this).trigger('mouseover');
})
Solution: https://github.com/alexgibson/tap.js
I have a conflict between 'touchend' and 'touchmove' events on the iPad in mobile Safari. I have images sitting next to each other like a gallery and they have a 'touchend' event attached to flip when touchend. However, you can also slide from one image to the other (like on iPhone sliding home screen to the next screen).
Now I can't figure out how to prevent the 'touchend' event from firing when I want to slide to the next image. Obviously, I don't want the image to flip if I slide, only if I tap.
My solution so far:
var img = $('.show-video');
var sliding = false;
img.bind('touchend', function(e) {
if (sliding === false){
Animate($(this), 'flip');
}
});
img.bind('touchmove', function(){
sliding = true;
$(this).bind('touchend', function(){
window.setTimeout(function(){
sliding = false;
}, 200)
})
});
````
I think this can be done much better.
You basically have two events when it comes to tapping the screen: touchstart and touchend. When a user touches the screen, the first event is captured, when he stops touching the screen, the second event is fired. The touchmove event should be captured to analyse the movement of the finger.
I'm not entirely sure what you're trying to say, but I'm assuming you you are capturing those events. What you can do is:
Instead of doing something on touchstart do it on touchend. This is more natural anyway, since something should happen after you lift the finger
After touchstart see if there is any movement using touchmove. If none and touchend is called, do what you wanted to do for a tap. If there was movement, do whatever you wanted to do for sliding.
I hope this helps.
I've made a workaround on this once.
You been already explained what are the events that are happening, and also you have a clue as a question.
For example lets say you have your gallery on a #galleryOverlay, and you scroller is inside it.
Then all you have to do is something like
$('#galleryOverlay').bind('touchstart touchmove touchmove', function(e){e.stopPropagation();})
So this way you keep your events inside your gallery, but you prevent them to happen outside.
Good luck
This library adds a 'tap' event which you can use to watch for a "tap" instead of "touchend".
https://github.com/alexgibson/tap.js