Get mouse coordinates when the mouse is over a disabled element? - javascript

When using a global mousemove event attached to the window object, the mouse coordinates are not available when the mouse moves over a disabled element. Disabled elements do not fire any events, presenting a problem.
Part of my application includes a free-transform tool which allows elements to be rotated, scaled, resized and dragged around the viewport (drag & drop). The flow of my app is broken if the mouse is moved over a disabled element while freely transforming an object, because suddenly the mouse coordinates are not available to my objects until the mouse leaves the element, giving a choppy / laggy feel and a poor user experience.
I've tried the readonly attribute instead. However, this is not a viable solution as it is only supported by two elements (input and textarea) source: https://www.w3.org/TR/html4/interact/forms.html#h-17.12 and has different behaviour.
Here's a Fiddle showing the choppy / laggy behaviour: https://jsfiddle.net/rmw9anLs/2/
I understand the element itself doesn't fire any events, but I'm not attaching any events to the disabled element. I would expect the window.mousemove event to fire regardless and don't understand why a disabled element on the page would interrupt a global event listener.
Aside from implementing a custom disabled feature using JavaScript, is there a way to get the mouse coordinates without having to account for the mouse being on top of disabled elements?

You cannot, hence the disabled attribute has no effect, other than making your HTML invalid.
To stop the mouse event working, attach an event handler to the element using event.preventDefault() on it, check for a data-disabled attribute on the element in your existing click handlers or use pointer-events: none in a CSS class which you toggle on/off as needed. Also be aware that pointer-events is not well supported in IE <11
E.g:
https://jsfiddle.net/x4nLu0a5/

Related

Binding Multiple dragenter/ dragleave Events in HTML5 Drag 'n Drop?

Here's a basic example of what I have going on here:
http://jsfiddle.net/kgqkM/2/
What I'm trying to do is dedicate the area outside of this list to be a "delete" area where I can set up the appropriate logic to remove the dragged element from the page. I'm attempting to show when the user drags the element off the list it would color the outside red/ semi-transparent. When I set events on the outer-wrapper, they seem to take over all the dragenter/ dragleave events.
Guessing my issue has to do something with setting the event on the parent div? I'm starting to try and perhaps have one master event on top and deciding what to do based on the e.target and .parents('.switch'), but insofar it's resulting in buggy behavior.
It would seem that I had to do some (correct) logic on the event target. I have to refactor my code a bit, but it's working out.

Javascript IE mouse events restricted to original recipient?

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.

What mouse/touch events should I use to cause a div to change color when cursor is dragged over it?

I'd like to know what mouse events I need to use for the task below.
When a cursor is dragged over a div, the div changes color.
By dragged I mean that the mouse button has been clicked once (and not released) somewhere outside the div and then the cursor has been moved over the div (the mouse button has not been released at any time during this process).
The div shouldn't respond to onmouseover. The mouse button needs to have been depressed and then dragged over the div to activate the change in the div.
I'm also wondering if there are any equivalent events for touch devices?
If i understand this right you can do the following:
set a global variable "mousedown" to false
use the "onmousedown" event to set "mousedown" to true
use the "onmouseover" event of your div to fire a function where you first check if mousedown is true and if so make the div visible
use the "onmouseup" event on your page to set "mousedown" to false again
For anything javascript related to touch event you should have a look at Sencha Touch
EDIT: If you want to avoid such frameworks. You should have a look at The HTML5 Specification. There are a couple of new events related to touch devices.
Here is a nice article about it:
http://www.html5rocks.com/en/mobile/touch.html
I'd recommend JQueryUI for this - it has several drag-specific events built-in. The drag event for touch devices is called touchmove

why not use mouseup event target rather than position for "old school" drag-n-drop?

So, from what I've seen nearly all the IE compatible drag-n-drop use positioning to determine where something is dropped. Doing something like mousedown, determine the position of all droppable, mouseup determine if we are in a droppable position. Why? I made a quick prototype, and it seems to work, which uses the event.target on mouseup (in jquery, so whatever that translates to elsewhere) to determine the drop element.
Is there a compelling reason not to do this? (use the e.target on mouseup). So, mousedown determines what is being dragged, and mouseup determines where it is dropped. Add some variable to make sure we're dragging, and remember what is dragged.
My guess: Because e.target on mouseup can refer to the element you're dragging (or its drag-ghost). If you drag an element, and it (or a translucent ghost-element) follows your cursor like when dragging a file on your desktop, your mouse will always be over the element you're dragging, when you mouse-up.
Alternatively, if there's no cursor-following, and no ghosting, e.target might refer to an element inside the "dropzone element" and not the dropzone itself.
For instance:
<div id="dropzone_element">
<div id="previously_dropped_element" />
<div>
<div id="draggable_element" />
So if you drag the draggable element over the dropzone element and release the mouse, you're actually releasing the mouse over the previously dropped element inside the dropzone; not the dropzone itself.
In both cases, checking the mouse position is the only way to get the proper dropzone element.
Those would be my guesses, but I don't have IE to check the actual behavior.
Edit: In the 1st case position-checking is the only way. In the 2nd case, you could also check the target's ancestors to find the dropzone element, as pointed out by aephus in the comments. If, that is, the previously dropped element has actually be inserted into the dropzone's hierarchy, and not just been positioned to look like it is - although that would be a really weird thing to do :)
The first quess: there is always lagging when you drag elements, especialy in IE. And mouse pointer can outrun or fall behind the dragging element. So on drop, pointer is not actualy over the dragging element, and - for small drop zones - not over the drop zone. Ajax libraries have to take this fact into account. And the only way to make it work predictably is to compare coordinates of dragging target and the drop zone.
The second quess: ajax libraries may give you an opportunity to use the drop handler. The drop handler is an element which is not child of the dropzone but it is covering the dropzone. And in this case there is no way to catch events by dropzone. But comparing the coordinates is still working. Why would someone cover the dropzone? Let's assume one has table. And one of cells is the dropzone. And now one wants to catch mousewheel event. One creates div (#scroller) with the same size as table and places it over the table. Then he puts another div (#eventgrabber) inside scroller. Eventgrabber is heigher then scroller. Now one is able to catch scroll event on scroller. But in order to be able to drag cells one have to assign eventgrabber as drag&drop handler.

Detect if mouse button is down when the mouse entered active area (mouse was pressed down outside this area)

I am new to JavaScript so I might be missing something obvious here, but this is the problem. I am not getting the mouse down / up event if the event happened outside the active area under JavaScript control, so if the mouse enters the active area (onmouseover event) with the left button down, is there a way to know that the button is down?
Added info : Ideally, I would like to keep track of the mouse even outside the browser window - the way Google maps does - try clicking down the mouse button and move outside the browser - this works in chrome and with some quirks in Firefox. Is it possible to do this while remaining within the bounds of JavaScript or is it some proprietary stuff?
Yes: ensure that the mouse event handlers to detect a mouse-down event are attached to some element that occupies the entire viewport. For instance the HTML (document) element...

Categories