I need to manually construct/fire a mousedown event in a way that can be handled by any relevant event handlers (either in straight JS, jQuery, or interact.js), just as a natural mousedown event would. However, the event does not seem to trigger anything the way I expect it to.
I am trying to make some irregularly shaped images draggable using the interact.js library. The images are simply rectangular img elements with transparent portions. On each element, I have defined 2 interact.js event listeners:
- Checking if the click was inside the image area, disabling drag if not (fires on "down" event)
- Handling the drag (fires on "drag" event)
However, if the img elements are overlapping, and the user clicks in the transparent area of the top element but on the filled area of the lower element, the lower element should be the target of the drag. After trying several things (see below), I have settled on the solution of: re-ordering the z-indexes of the elements at the same time that I disable drag in step 1, then re-firing the mousedown event on all lower elements. I'm using the "native" event type (not jQuery or interact.js) in hopes that it will literally just replicate the original mousedown event.
// code to re-assign "zIndex"s
function demote(element, interactible, event){
// block dragging on element
interactible.draggable(false);
// get all images lower than the target
var z = element.css("zIndex");
var images = $("img").filter(function() {
return Number($(this).css("zIndex")) < z;
});
// push the target to the back
element.css("zIndex",1);
// re-process all lower events
$(images).each( function () {
// move element up
$(this).css("zIndex",Number($(this).css("zIndex"))+1);
// re-fire event if element began below current target
elem = document.getElementById($(this).attr('id'));
// Create the event.
e = new MouseEvent("mousedown", {clientX: event.pageX, clientY: event.pageY});
var cancelled = !elem.dispatchEvent(e);
});
}
Unfortunately, this does not work, as the mousedown event does not register with any of the handlers. Why?
I have all the (relevant) code at this JSFiddle: https://jsfiddle.net/tfollo/xr27938a/10/ Note that this JSFiddle does not seem to work as smoothly as it does in a normal browser window, but I think it demonstrates the intended functionality.
Other things I have tried:
Lots of people have proposed different schemes to handle similar problems (i.e. forwarding events to lower layers, using pointer-events: none, etc), but none seem to work to trigger the interact.js handler and start a drag interaction on the right element. I also tried using interaction.start (provided by interact.js) but it seems buggy--there is at least one open issue on the topic and when I tried to start a new drag interaction on a target of my choice I got lots of errors from within the library's code.
I'm not against revisiting any of these solutions per se, but I would also really like to know why manually firing a mousedown event won't work.
Event
objects - you have to use static methods such asdocument.createEvent()
or something. – Kuo