I have created an app with three.js were there are 2 renderers (1 canvas and 1 div(css renderer)).
The css renderer is on top of the canvas and I would like to pass any type of event to the canvas element which is behind. So far I have failed to create a dispatcher...
What I have tried so far:
1)
// on top element css renderer
$(this.cssRenderer.domElement).on("click mousedown mouseup mousemove focus blur keydown keyup change touchstart touchend touchmove", function ( event ) {
event.preventDefault();
event.stopImmediatePropagation();
//canvas background domelement
$(that.renderer.domElement).trigger(event);
});
2)
$(this.cssRenderer.domElement).on("click mousedown mouseup mousemove focus blur keydown keyup change touchstart touchend touchmove", function ( event ) {
event.preventDefault();
event.stopImmediatePropagation();
that.renderer.domElement.dispatchEvent(event.originalEvent);
});
In case 2 I get the following error:
Uncaught InvalidStateError: Failed to execute 'dispatchEvent' on
'EventTarget': The event is already being dispatched.
I also tried to copy the object or pass it after some timeOut but nothing seem to work.
I haven't done anything similar so I'd like a little help or some guidance.
You can't just pass event to your trigger function, as event is an object and trigger requires a string as an argument.
Instead, try passing event.type instead:
$(that.renderer.domElement).trigger(event.type);
Read up here.
JSFiddle (or with mouse coordinates)
To also pass mouse coordinates I am passing an object (mouse) as well as the event type.
Related
I'm developing an JavaScript app which needs to trigger mousemove event, and I am using tampermonkey to "embed" it on websites to test if it works on them. On one website, the mousemove event is simply blocked (I don't know why) and even console.log within this event doesn't show. It seems like this event has never triggered (the website ignores).
Is it possible to "override" events and block them? If so, how can I override this action and enable my specific mousemove event?
This script won't work:
document.addEventListener("mousemove", function(e) {
e = e || window.event;
e.stopPropagation();
console.log("[HELLO] Is it moving?!");
}, false);
(the result will be... nothing. this won't be logged)
Update They set window.onmousemove as null. Is there any way to revert this?
If you can run your code before theirs, you can save the function
window.onmousemove = function() {
console.log("moving",new Date())
};
window.myMove = window.onmousemove;
document.getElementById("x").addEventListener("click",function() {
window.onmousemove=null
})
document.getElementById("y").addEventListener("click",function() {
window.onmousemove=myMove;
})
<button type="button" id="x">Turn off mousemove</button>
<button type="button" id="y">Turn mousemove back on</button>
If some other event handler called stopPropagation() on the event, it won't be propagated up to the document level during the "bubble" phase.
However, you can make your event handler be called sooner, by running it in the "capture" phase. Simply change the third argument from false to true. This will solve most issues, except if some other event handler on the document was added before yours, and calls stopImmediatePropagation on the event. But this is rare.
See Bubbling and capturing explained for more background information.
In my simple application canvas wrapped by hyperlink. Some objects, which are placed on canvas stage have special mouse interaction on click event. Is there any possible solutions to prevent hyperlink jumping by clicking on objects with my mouse click event listeners?
Normally you can just call preventDefault on the generated mouse event, and it will stop the link event from firing.
element.addEventListener("click", function(e) {
e.preventDefault();
}, false);
This is not possible using EaselJS because although you can access the nativeEvent on any EaselJS mouse event, EaselJS doesn't use the "click" event at all (and instead uses a combination of "mousedown" and "mouseup"). So preventing default on a click event will do nothing.
Doesn't work
// You would expect this to work.
myShape.on("click", function(e) {
e.nativeEvent.preventDefault(); // Nothing. This cancels a "mouseup" instead.
});
Workaround
However, you can work around this pretty easily. Set a flag on the clicked item (or wherever you would set it in your application) any time it is clicked.
myShape.addEventListener("click", function(event) {
myShape.clicked = true;
}, false);
Then, listen for the canvas click event yourself, check and check the flag. Make sure to reset it after. This is possible because "click" is always fired after "mouseup"
stage.canvas.addEventListener("click", function(event) {
if (myShape.clicked) { event.preventDefault(); }
myShape.clicked = false;
}, false);
Here is a quick fiddle showing it working. http://jsfiddle.net/buqkvb1u/
We are looking to see if this makes sense to handle in EaselJS. Thanks for your report!
I've been having trouble getting stopPropagation to work for my dataview. Basically the issue is as follows;
Select node in the dataview, this fires the select, selectionchange events
Selected node has an image with an onClick event, this creates a report in a pop up window.
When image is clicked I call stopPropagation to prevent the event being bubbled up to the dataview which would cause the deselect, selectionchange events to be fired.
stopPropagation only seems to work in Firefox for me. Chrome and IE it seems to have no effect as the node is deselected and the unwanted events fired.
I've tried the following function on the onClick event
handleBubbleEvent: function(e) {
if (!e) {
var e = window.event;
}
e.cancelBubble = true;
e.returnValue = false;
if (e.stopPropagation) {
e.stopPropagation();
}
}
Have also seen stopImmediatePropagation, preventDefault, stopEvent but these also has had no effect
I am doing all this inside an Ext XTemplate
I'm wondering if this is an ExtJS 5 issue and the same code is working for an older version of ExtJS. I just can't seem to stop the click event bubbling back up to the dataview which then fires the deselect and selectionchange events.
Could it be that it is a timing/order issue. I use ExtJS's selectionchange event on the dataview whereas in the XTemplate I am using my own listener function? I see stuff online referencing capturing/bubbling of events and as I'm not a web developer I'm struggling on this.
UPDATE:
I'm now looking at events and capturing/bubbling, it seems the capturing is going up to the parent and calling the deselect, selectionchange then going down into the actual click handler at which point I then call stopPropagation but it is too late at this stage. Looking at creating my own listener for selectionchange with either target/delegate set so that it is only called when class != 'some class' and then a listener on 'some class' click to handle what I want and stopPropagation, if that makes any sense!
Try using a setTimeout on any dom manipulation triggered by the event.target element's event handler so that the event bubbling completes before any of the dom manipulation occurs.
I had the same issue with Chrome, and (like with you) Firefox worked. I discovered that Chrome seems to get confused if you modify the dom before the event bubbling completes.
In my case, I was adding two elements to the document.body (a canvas and a fieldset) and by the time chrome bubbled the event, the event.target was incorrect (it thought "BODY" was the event.target.tagName -- WRONG!). I wrapped the DOM manipulation portion in a setTimeout like this:
setTimeout(()=>
{
document.body.appendChild(canvas);
document.body.appendChild(fieldSet);
},0);
After this, chrome started reporting the correct element.target on the bubbled body click event. Maybe this same technique will help you get e.stopPropagation() to do its thing before the dom manipulation occurs.
I'd like to cancel the MouseEvent that is fired on object:moving in fabric.js, to prevent all the actions when some condition is met. I tried to set cancelBubble = true or simply return false; but with no success. Any ideas?
Sample fiddle with some event:
http://jsfiddle.net/fabricjs/S9sLu/
Mouse mouse:moving event is continuosly fired while mouse pointer is on canvas. But by checking event.target you can check if that's a generic or object related move.
canvas.on('mouse:move', function(options) {
if(options.target) {
//suppress event handlers here
}
});
Is there a possibility to programmatically call the mousemove event in jQuery?
Obviously, I'm not going to change the actual position of the cursor - it's impossible. All I want is re-call this event so all other scripts that have attached their handers to it will also be called.
To trigger event handlers bound to the mousemove event you can use trigger()
$('#elementID').on('mousemove', function() {
// do stuff
});
$('#elementID').trigger('mousemove'); // triggers above event handler