Detecting unhandled mouse events - javascript

The question is probably a bit more complex than the title might make you believe, but in the end it nails down to that question. But first let me show you the bigger picture:
I am using chromiums rendering/content/javascript engine for user interfaces in my application. Below the user interface though is a real 3d world that also needs to be informed about interaction. So you can imagine my user interface like a regular html page where the body is transparent. So whenever i get a message for the user interface (like mouse move, mouse down and so on) i need to be able to detect if that message was handled by the user interface or if it should be propagated to the world "below". All this only has to work in chrome, other browsers are unimportant.
So far i had the following ideas (i keep using mouse move as an example):
Attach a mouse move handler to window (or html or body) and when its hit -> deliver to the application. Problem here is that events get propagated up the chain no matter if handled or not
Attach a mouse move handler to window and check if the event target is html or body. Problem here is if i have like a tansparent container div thats only used for positioning or arranging child nodes i will get this element if its hovered even tho it should go to the world there
Attach a mouse move handler to window, mark elements that should not capture the mouse (like transparent divs) with an attribute and in the mouse move handler check if the target has such an attribute. If yes, then fire the event, else its handled. Problem here is if one of these nomouse-elements is over an element that wants to capture the mouse i miss it
Attach a mouse move handler to window, mark elements that should not capture the mouse with an attribute. Add a mouse move handler to all elements that do not have the no-mouse attribute and set a property to true. in the window mouse handler check if that property in the event object is set. This could work i think.
Is my last idea feasible? Do you know of a better way to achieve this? Greetings and thanks in advance.

You could try to make a transparent div over the whole screen and attach the mouse handler to it. Use the z-index for placing the clickable elements in front of it.
The whole screen div CSS:
html, body {
weight: 100%;
margin: 0;
}
#whole-screen {
min-height: 100%;
}

Related

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

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/

How to create a move handle using jquery

This is more the theoretical type of question.
In my web-application i want to create a button that the user can click and therefore initiate a move-mode during which (until the mouse is released) all the mouse movements are being translated onto a certain DIV.
To better understand what i mean, think of a box in which to show a portion of an image (box is overflow:hidden) - i want to make it possible to move the image around within the box, but not by directly dragging the image, but by dragging a handle instead (a handle that does not move when dragged)
In the optimum case the mouse cursor hides while the drag operation is on.
My basic idea was to use a draggable but i got no clue on how to make it accessible, yet invisible.
How would i accomplish that using javascript/jQuery?
Making the cursor invisible isn't too difficult, see the top two answers on this question.
As for the handle, you could try using jQuery UI Draggable's handle option. The key to making the handle appear stationary is to have a separate element that looks like the handle, and position the real handle (which would be an empty element) on top of it.
You would then position the real handle back where it was, covering the fake handle, when the stop() event is fired.
So, in the start() event, you would add a class to the real handle that makes the cursor invisible (using either of the methods in the post mentioned earlier), and remove that class when the stop() event fires, causing the cursor to reappear.
The easiest approach would probably be to just apply different CSS styles on the click event of the button.
Add a class to your element (on click) for the :hover pseudo-class that has cursor: move; for its style and has cursor: none; for the :active pseudo-class. You could then have these styles removed once the user's mouse left the draggable area.
On click the function might look like this:
$('#myButton').click(function(){
$('#myDraggableElement').addClass('draggable');
});
$('#myDraggableElement').mouseLeave(function(){
$(this).removeClass('draggable');
});
Have I understood the question correctly?

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.

'onmouseover' working unexpectedly in Javascript

I have a div in which there is a link. When a user takes the mouse pointer over the link, I call the basic_nav_mouseover() function which changes the background-image of the parent div. I have also added the function basic_nav_mouseout to the ommouseout attribute of the parent which should set the background-image of the parent div to none when the mouse pointer leaves the div. However, strangely, the function basic_nav_mouseout() is getting called as soon as the mouse pointer in leaving the link in the parent div. Here is a test page : http://spats.in/test/. Look at the links 'about' ,'people','connect' on the top right corner.
Where am I going wrong?
There's a really good explanation of the limitations of the mouseover and mouseout events in the jQuery docs (about half way down that page).
Mouseover and mouseout events trigger when you move the mouse over the bound element, as expected, but they also fire a separate event when you mouse over any inner elements within the parent element - this is obviously undesirable in most circumstances.
Basically, to fix your problem, use the mouseenter and mouseleave events instead.
From a user experience point of view, I'd encourage you to bind both events to the link, so that the special background colour actually indicates that the link is active - I think I'd find the effect you are trying to achieve quite misleading, because the highlighted background would make me think that I can still click the link, even though I cannot..
If you want to keep the visual effect you've current got (with a tall coloured area behind each link), make the link take up the whole box - i.e. 100% of the height and width of the div.
If onmouseover is set on the link, onmouseout should be set on the same element.
onmouseout gets triggered every time a child node is hovered over, you need to check the calling target.
http://www.quirksmode.org/js/events_mouse.html is a good resource.
I'm no javascript expert, but shouldn't you wait with binding the function to the event until the page is fully loaded? So:
window.onload = function(){
$('.item1').bind('mouseleave',basic_nav_mouseout);
};
Also (correct me if I'm wrong) I don't think you have to give the object as an argument in 'basic_nav_mouseout('.item1','red')', you can just use the 'this' keyword. So:
function basic_nav_mouseout(){
this.css('background-image',"none");
}
I don't know anything about the JQuery library though, my only (little) experience is with the Prototype library.

z-index and Javascript events

I have a couple of divs overlaid on each other with differing z-index values.
The default behaviour for browsers seems to be the event bound to the top-most z-index div gets fired. I.e. I have multiple onclicks one for each div but only the top one is fired when the area is clicked.
Is there a way to fire the events attached to all divs no matter what the z-index of each is, so long as the action is 'over' that div without regard to z-index?
The event doesn't actually occur on the element that is obscured by another unless the other element is contained in the first, then it will bubble up. The only way that I can think of to achieve what you want is to go through all of the potential elements and see if any of them contain the point at which the click occurred and trigger a click on that element (if it's not the current one).
If you are using an javaScript framework event bubbling might be included. (ExtJS I know for sure has this kind of event feature.)

Categories