Dispatching an event means firing it. the following code will fire the click event of the button 2 times.
let event = new Event("click");
elem.dispatchEvent(event);
elem.dispatchEvent(event);
<button id="elem" onclick="alert('Click!');">Autoclick</button>
Javascript has classes that are listening to the user events (click, hover a button, press a key). That classes are the event dispatchers. What does "dispatch a event" means?
The event dispatchers manage the event in order to "understand" which action has made the user and react with the behaviour that the developer coded.
Javascript has some event dispatcher classes defined by default, but some libraries like JQuery let you create custom events.
To understand a custom event, you can think this example: You are programming a clock class that you will use in the future. You code all the methods to make the clock work. Further, you declare a new event that triggers when a second passes. Let's call it "timestep".
Now imagine you use that class in two different programs. You can implement a different behaviour in both programs by inserting code in the "timestep" event.
In this example, I created a custom event that fires when the user moves one handle. It's behaviour consist in modify the label to the time the handle is on. Check it here:
http://ytcropper.com/crop/hsceS7udV4g
Related
I'm currently trying to write a small game engine for the canvas in vanilla javascript, in my current mental model of how it would work, the user would instantiate a Scene class that would contain all objects to be rendered as well as their behavior. There would only be one active scene at a time per canvas, so that scenes that are not currently loaded are inactive. As such, I'd like to be able to redirect all events that are dispatched to the canvas to the currently active scene. It would look something like this:
canvas.addEventListener(/* all */, (e) => activeScene.dispatchEvent(e));
but obviously this does not work.
There is an interesting answer to a similar question here: Listen for all events in JavaScript
that goes something along the lines of iterating over all window properties and registering an event listener for all properties that start with "on".
Problem is, this won't catch custom events, and I'd like to enable the user to interact with their scenes using custom events dispatched from other places (for example a button above the canvas to reset the current level could send a 'reset' event).
The alternatives would be:
the user calls a custom function on the canvas that then calls the appropriate function on the currently active scene
The user dispatches a custom event as I was thinking but also has to add an event listener for that event type and redirect the event to the active scene manually (or I provide a function to register the custom event and redirect events of this type to the active scene)
In all those cases it's a 2 step process for the user. I guess registering all custom events once at the start of the program wouldn't be that bad but I was wondering if there existed a more elegant solution.
Alright, after some tinkering here is the solution I came up with:
I redirect all standard events using eventListeners with this code
for(let key in myObj){
if(key.startsWith('on')) {
myObj.addEventListener(key.slice(2), (e) => {otherObj.dispatchEvent(e)});
}
}
and I overwrite the default dispatchEvent() method so that all manually fired events are redirected regardless of their type:
myObj.dispatchEvent = (e) => {otherObj.dispatchEvent(e)};
Unfortunately the first part is necessary because standard events are not fired through the dispatchEvent() method. In theory this should redirect all events fired on the object (which in my case would be the canvas) to the other (the active scene).
Could someone explain to me what exactly this means
trigger executes the code for the event handler but not actually executes the event itself?
Consider the following code:
$('#parent').on('click',function (event){
console.log(event);
});
$('#parent').trigger('click');
trigger does produce an Event object since it consoles it. So, in which way it does not execute the event?
jQuery has a rather nice event system, that handles events in a more complex way than the basic event bubbling. For instance it allows multiple events, of the same type, on an element.
That means that jQuery events sit on top of the browser events and add features. When you trigger a jQuery event it just send messages up the jQuery DOM tree, which causes things to respond, but it does not necessarily generate the native browser events.
You can still hit the native event generation by using the underlying DOM elements and methods that jQuery wraps:
// This will generate a click event "for jQuery to hear"
$('#parent').trigger('click');
or this does exactly the same as above:
$('#parent').click();
Whereas this will fire the native DOM click event "actually clicks the button/link":
$('#parent')[0].click();
Update (from A. Wolff):
Some jQuery click events are passed on to the native click event. An exception being anchor links (which do not). I would have to test it to see if native clicks are generated or not for buttons and other inputs.
In short
Is there a way in which, when listening to a native event, I can detect if the event was somehow used by CKEditor before it propagated to my listener, or prevent it from propagating at all?
Use case
I'm listening to the keyup event using jQuery, to detect when escape is pressed. When it is, the user is prompted if they want to discard changes, and the CKEditor instance is destroyed and its element removed from the DOM.
$('body').on('keyup', function(e){
if(e.which==27){
CKEDITOR.instances.myDiv.destroy();
$('#myDiv').remove();
}
});
The problem here is that CKEditor allows the user to interact with certain UI elements using the escape key. For instance to close a dialog window or drop-down list.
So my event should only execute its code if CKEditor did not already use the event to close a UI element of its own.
Attempt
I tried to listen to the dialogShow and dialogHide events to detect if a dialog window is open, and my action should thus be ignored. This didn't work for two reasons:
CKEditor handles the event first, so by the time the event propagates to my listener, no dialog windows are open and my code is executed.
Even if it would work, it wouldn't for drop-down lists as they do not trigger the dialog* events.
Ideas
I don't know enough about the workings of CKEditor to come up with a solution, but I think I'm looking for something along the lines of:
A setting in CKEditor to prevent event propagation: CKEDITOR.instances[0].noEventPropagation = true
An indication in the original event object: if(event.CKEditorWasHere){/*do nothing*/}
A plugin providing functionality that I can use.
Worst case scenario: A setTimeout in the dialogHide event which I'll use to suppress my own events for a short time.
So
Maybe I'm completely overlooking something. This seems to me like a common problem which should have a simple solution.
Thanks for your time.
I'm customizing an existing ASP.NET 3.5 AJAX web application that I can't modify the source code to (it's SharePoint 2010).
I need to add a click event handler as the first event on a Close button. However, I'd like to check what the existing event handlers already registered on this button do first, so I don't mess anything up.
I'm still learning ASP.NET AJAX and can see the Sys.UI.DomEvent class has methods to add and remove event handlers, but not enumerate them. I know jQuery and am familiar with JavaScript debugging in Chrome.
How can I see which events are registered and insert a custom event handler at a particular position?
There is a technique that will at least allow you to be the first in line (unless another script employs the same trick - unlikely).
What you have to do is hijack the click event. This related question demonstrates the technique: Hijacking onchange event without interfering with original function
All we do is redefine the click function to be one of our own choosing, e.g.
var myButton = document.getElementById('button1')
var oldClick = myButton.click;
myButton.click = function(evt) {
//do whatever you want. When done, call the default click function:
if (oldClick) oldClick(evt);
}
(the syntax in the linked question is superior, but the above code is easier to read).
I have a scheduler control, and some divs which can be dragged into the Scheduler which are two separate controls, now I have a problem, I succeeded to make the drag and drop event, when I drop I created an alert to get the coordinates where the drop was made see img below:
Now what I need to do is simulate a click event so when the user makes a drop an automatic click event is triggered (to trigger the add new event function of the scheduler)... anyone has any idea of how to achieve this?
Now what I need to do is simulate a click event so when the user makes a drop an automatic click event is triggered (to trigger the add new event function of the scheduler)... anyone has any idea of how to achieve this?
Don't try to simulate the click; instead, have both the click event and the drop event call a central, reusable function. While there are legitimate reasons you might want to simulate a click event, normally that's not how you solve this sort of problem.
Define the handler externally. Instead of ... ('click', function(event){}) do var handler = function(event){}; ... ('click', handler) and then you can easily do handler.call(this,event);.
A Pub/Sub system of any sort would handle this in a more loosely coupled way. For jQuery there is a really tiny but good one at https://gist.github.com/661855
If you're using any other framework you're likely to find others to suit you.