How to click-through a div without losing its hover events? - javascript

I have 2 divs stacked upon one another. I want to be able to receive click events for the bottom element without losing hover events for the top element.
If I assign pointer-events: none top the top element, the click-through works, but then I lose the hover events for the top element.
How can it be done?

The MDN docs clearly says that's what is supposed to happen:
none
The element is never the target of mouse events; however, mouse events
may target its descendant elements if those descendants have
pointer-events set to some other value. In these circumstances, mouse
events will trigger event listeners on this parent element as
appropriate on their way to/from the descendant during the event
capture/bubble phases.
https://developer.mozilla.org/en-US/docs/Web/CSS/pointer-events
What you can do is write a jQuery script that captures the clicks and transmits them.
jQuery("top-div").click(function(e)
{
e.preventDefault();
jQuery("bottom-div").click();
});
Something like that...

Related

How to make an element the default target of the scroll wheel?

I have many elements in a webpage of my APP.
How to make it so that whenever the cursor is not hovering over any of the scrollable elements, then it will automatically target a designated element?
When the user uses the mouse wheel or the arrow buttons when not on any element that's scrollable (including the <body>), no scroll event is fired. This is also the case when the user attempts to scroll up when at the very top, and when they attempt to scroll down when at the very bottom.
So, a scroll listener won't work. You probably need to instead listen for mouse wheel events instead.
You probably need:
A wheel listener on the window (so it listens to all wheel events)
From the event's target - the element that the event was dispatched to - determine if it is ever scrollable. Do the same for all parents. While you can do this programatically, to an extent, it'd be easier if you identified which elements are scrollable, and then just check to see if any of the parents match that. if (e.target.closest('.scrollable1, .scrollable2')) return;
If that condition is not fulfilled, then the user attempted to scroll when not over a scrollable element - so you can then call .scrollTo on the desired target element.

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/

custom drag and drop HTML5

I am trying to use drag and drop to reorder elements in the list (pure javascript). I would like to stylise the "ghost element" during the drag operation. Since I read that there is no way how to do that standartly, I am creating duplicate element (styled as I want) positioned exactly where original element should be during drag operation and its position is updated inside ondrag event.
Problem is that since this duplicate element is always exactly under cursor it is impossible to capture dragover or dragenter events on other elements. No matter where in the DOM is the "duplicate" element linked it always blocks ondragover. If I move the duplicate element so its not under the cursor it works but that defeats the purpose of seamless duplicate element.
Is there some way how this duplicate element would be ignored so elements that are underneath it would get the ondragover event instead? Normally event just bubbles towards parent of where the duplicate element is linked.
Got it working. It seems that it works (ghost element is not blocking the events) if its class has :
.duplicateGhostElementClass {
pointer-events: none;
}
Perhaps it saves someone some time.

propagate mouse events to obscured elements

Is there a way in JavaScript to propagate events to elements obscured by another one? Because I have an element with position: absolute that obscures elements that aren't parent elements of it, but I'd like click, mousemove and mousout events to pass through this element. The solution can be Mozilla Firefox specific, because I'll use it in a Firefox Add-On.
Maybe the css property pointer-events:none; is what you looking for. It's used on the twitter homepage for example, so you can click on the text in the "trending topics" also when it overlay by fade out graphics.
You could use getElementsByTagName("*") to get all elements in the page. Using a find-world-position function, you could get the position of an element relative to the top left corner of the page. You could now use offsetWidth, offsetHeight, and mouse position [browser specific, lol] to check if the cursor is over your element.
If the cursor is over your element, fire the event.
The above function should be attached to window.onmousedown/onmouseup/onmousemove/whatever

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