MDN says:
The setPointerCapture() method of the Element interface is used to designate a specific element as the capture target of future pointer events. Subsequent events for the pointer will be targeted at the capture element until capture is released.
And it works as expected if I call setPointerCapture in pointerDown callback: example - here you can drag yellow square as fast as you want and it will follow the cursor until pointerUp event happens.
But if try to capture target in pointerMove callback it won't work as I expected: example - yellow square follows the cursor until cursor hovers the square. If you move your mouse too fast square will stopped.
How this behavior can be explained? Did i misunderstand the documentation?
Not exactly.
The specs ask that
The pointer MUST be in its active buttons state for this method to be effective, otherwise it fails silently.
To be in its active buttons state means:
The condition when a pointer has a non-zero value for the buttons property. For mouse, this is when the device has at least one button depressed. For touch, this is when there is physical contact with the digitizer. For pen, this is when either the pen has physical contact with the digitizer, or at least one button is depressed while hovering.
So if your pointer device is in this state when you first move it over your element, or from any other event for that matter, it should work, until you release your pointer device.
However note that for your code to work in Firefox you need to preventDefault() the pointerdown event. But from Chrome, with a mouse device, you can start by dragging outside of the element, then move over it and the capture will work as intended.
The problem with your code is that it doesn't check if the capture did work, raising the captured flag unconditionally. Instead of this flag, check for element.hasPointerCapture(e.pointerId).
Related
I am working on functionality to copy event with keyboard Ctrl key pressed and then drag & drop the event with the mouse. It works pretty good now but I reached to the point where the original event is not visible during dragging which looks strange and must be avoided somehow.
Is there an option or workaround to avoid this disappearing of the original event during dragging? Perfect would be to display the event with some transparency during each dragging.
Here I prepared one sandbox for easier testing:
https://codesandbox.io/s/thirsty-cookies-veh6ow?file=/src/DemoApp.jsx
Please pay attention that in this sandbox, by some reason, you need to keep mouse on focus with the testing area or right. Just click on the text input on top before start testing the functionality in case it is not on focus. Then you must be able to copy each event by dragging it with left mouse key and keyboard Ctrl key pressed down.
On iPad the vmousemove event is triggered even when no move has been performed. Why's that?
Steps to reproduce:
Open http://jsfiddle.net/dcbV7/
Tap A div then B. Only tap them, but fast
Result: you see vmousemove event is triggered
vmousemove simulates the movement of a mouse. It would be as if you clicked A div, moved the mouse to B, then clicked it. There would be no other way to get a mouse from one to the other, after all.
If you try this on a device with a mouse, you'll notice that vmousemove is triggered every time the mouse is actually moved. The best heuristic they have for mouse-less environments is that touching two points close together in a short amount of time is similar to doing the same with a mouse.
I have an app that uses mouseup and down to draw elements. The problem is that if for any reason the mouseup event is not fired after mousedown ( let's say I introduce an escape key that cancels drawing the new element), the element would be "incomplete", and hence it would cause problem. So I want to know if there is any mechanism that I can use inside mousedown to ensure that mouseup is fired after it, and if not, destroy the new element ?
You're gonna have to destroy the drawing on the events which you can think of that would make the mouseup not fire following the mousedown -- pressing keys, releasing the mouse outside of the drawing region, right clicking while left click is still holding down, switching the window with alt+tab while drawing, computer being struck with lightening in the middle of a tornado while drawing, etc.
I have an info overlay that works great in Chrome and FF. It is a div containing a table (for border image layout) and then a central content div. I trigger mousedown on the appropriate border table cells.
Once this happens, a different div is brought to the front with z-index, and that passes along the mousemove and mouseup events to handle dragging the info bubble around. Once the mouseup is fired, the info bubble puts the "event" div back to where it was.
I also follow the same process for dragging the lower right corner of the bubble to resize it. Again, works in Chrome and FF, but fails in IE.
IE seems to be restricting the event triggers to the info div. If the mouse manages to move outside the div (from dragging faster then the events fire/update), the info overlay no longer receives mousemove events. However, if I move the mouse back over the overlay (without releasing the button) it continues to receive mouse events.
Edit: In creating some example code (the current functionality is split across several JS modules), it worked in IE. As soon as I find the difference between my example code and the actual code, I will update again.
Edit/Answer: (SO wont let a new user answer their own question in this time span...)
Still not sure what the actual problem was. (If you ask me, a div with a z-index of 100 should be receiving mouse events just fine?)
My solution was to fix my mouse event handling such that I could attach my mousemove and mouseup to the parent div (as should have been done in the first place) for all dragging/resizing behaviors I wanted to set up.
The problem was due to a newbie approach to the events and having stopPropagation() in too many locations preventing me from taking such an approach. (I wanted text, etc in my info box to be selectable).
I adjusted the code so that my text containers only had to stop propagation on mousedown instead of all the mouse events.
I am in a situation where I need jQuery's mouseover event to be fired when an element (in this case an image) moves under the mouse, so unlike the common situation is an element that is moving, not the mouse.
Do you know of any library/gist/technology that could help me in this sense?
I've tried with flash but with no luck, is this something than can actually be done?
You can track mouse position by binding a handler to mousemove on the body, and calculate after every move of the image whether the pointer is over it.
I ran across a similar issue. In my case I did a "good enough" workaround by keeping track of the time the mouse last moved and then in the mouseover handler seeing if the mouse had moved recently -- within 30ms of the current time. That way I can bail out in cases where the mouse didn't actually move, but I don't have to test the hitboxes myself -- something very hard to do right and fast, and fortunately something I can leave to the browser by doing this.