Trigger keyboard event in vanilla javascript - javascript

I am trying to follow currently recommended way of triggering dom events (using event constructors that is) and it does not work for me (in Chrome)
This is my code (http://jsfiddle.net/artemave/shg7ot58/):
document.addEventListener(function(e) {
alert("hallo");
});
var e = new KeyboardEvent("keydown", {
key: "Escape", // keyCode: 27 also does not work
bubbles: true,
cancelable: true
});
document.dispatchEvent(e);

Add event type, keydown to the addEventListener method to listen for your custom dispatched event.
document.addEventListener('keydown', function(e) {
alert("hallo");
});
Fiddle: http://jsfiddle.net/shg7ot58/1/

Related

How to trigger keydown on an element in jasmine unit test

I am writing a jasmine unit test for a function that receives 'keydown' event. It's just a plain javascript(not using any framework)
var event = document.createEvent('Event');
event.keyCode = 84;
event.initEvent('keydown');
event.target = $('#selector');
myFunction(event);
When I console log the event in myFunction
This is what I get:
{"returnValue":true,"timeStamp":1607595872162,"eventPhase":0,"target":null,"defaultPrevented":false,"srcElement":null,"type":"keydown","cancelable":false,"currentTarget":null,"bubbles":false,"cancelBubble":false,"keyCode":84}
The 'target' property is null
How do I set the target value?
Please help
It looks like you're looking to dispatch the event you created. The MDN article I linked indicates the target parameter is used to initialize target in the event. In your case, I would do something like:
var event = document.createEvent('Event');
event.keyCode = 84;
event.initEvent('keydown');
$('#selector')[0].dispatchEvent(event);
This makes the assumption that you've bound myFunction to #selector's keydown event via:
document.getElementById("selector").addEventListener('keydown', myFunction);
or
$('#selector').on('keydown', myFunction);
If you're not binding the function with an event listener, you could leverage duck typing by building a fake event object and passing that fake event to myFunction:
myFunction({
type: 'keydown',
keyCode: 84,
target: $('#selector')[0]
});

Custom Event having same name as native event

First of all, I would like to know whether it is right to create custom event with the same name as native event ?
My requirement is, I want to dispatch a custom event "click" with additional data using Javascript dispatchEvent. If I do so, the event is fired twice. My code is given below:
button.addEventListener("click", (event)=>{
if(!event.detail || event.detail && !event.detail.fromComponent){
let eventObject = new CustomEvent("click", {bubbles: true, composed: true, cancelable: true, detail: {myCustomKey: myCustomValue, fromComponent: true });
}
});
To avoid infinite looping, I have added boolean key*fromComponent in the detail object. Is there any way to achieve my requirement?

Javascript - Dispatch built-in events [duplicate]

Does anybody know of a method to trigger an event in Prototype, as you can with jQuery's trigger function?
I have bound an event listener using the observe method, but I would also like to be able to fire the event programatically.
event.simulate.js fits your needs.
I've used this several times and it works like a charm. It allows you to manually trigger native events, such as click or hover like so:
$('foo').simulate('click');
The great thing about this is that all attached event handlers will still be executed, just as if you would have clicked the element yourself.
For custom events you can use the standard prototype method Event.fire().
I don't think there is one built in to Prototype, but you can use this (not tested but should at least get you in the right direction):
Element.prototype.triggerEvent = function(eventName)
{
if (document.createEvent)
{
var evt = document.createEvent('HTMLEvents');
evt.initEvent(eventName, true, true);
return this.dispatchEvent(evt);
}
if (this.fireEvent)
return this.fireEvent('on' + eventName);
}
$('foo').triggerEvent('mouseover');
I found this post helpful... http://jehiah.cz/archive/firing-javascript-events-properly
It covers a way to fire events in both Firefox and IE.
function fireEvent(element,event){
if (document.createEventObject){
// dispatch for IE
var evt = document.createEventObject();
return element.fireEvent('on'+event,evt)
}
else{
// dispatch for firefox + others
var evt = document.createEvent("HTMLEvents");
evt.initEvent(event, true, true ); // event type,bubbling,cancelable
return !element.dispatchEvent(evt);
}
}
The answers here are true for "Normal" events, that is events which are defined by the User Agent, but for custom events you should use prototype's "fire" method. e.g.
$('something').observe('my:custom', function() { alert('Custom'); });
.
.
$('something').fire('my:custom'); // This will cause the alert to display

Firing events on many DOM elements with javascript

I was wondering if it is possible to fire many events (not only one element with one type of event) at the same time in JavaScript on different DOM elements ("li" , "a" , " input", etc..) , I'm using the function fireEvent(element , event) to do the job with only one element and only one kind of event (onchange for example):
function fireEvent(element,event) {
if (document.createEvent) {
// dispatch for firefox + others
var evt = document.createEvent("HTMLEvents");
evt.initEvent(event, true, true ); // event type,bubbling,cancelable
return !element.dispatchEvent(evt);
} else {
// dispatch for IE
var evt = document.createEventObject();
return element.fireEvent('on'+event,evt)
}
}
How can use this function to fire many events on many DOM elements?
This can be done with jQuery.
$("elements").action1().action2()
Having queue:false will trigger all the actions at the same moment.
Dunno if I understood your requirement correctly.
http://jsfiddle.net/t8mr7/1/
All the 4 actions being executed at the same event trigger.

How do I programmatically force an onchange event on an input?

How do I programmatically force an onchange event on an input?
I've tried something like this:
var code = ele.getAttribute('onchange');
eval(code);
But my end goal is to fire any listener functions, and that doesn't seem to work. Neither does just updating the 'value' attribute.
Create an Event object and pass it to the dispatchEvent method of the element:
var element = document.getElementById('just_an_example');
var event = new Event('change');
element.dispatchEvent(event);
This will trigger event listeners regardless of whether they were registered by calling the addEventListener method or by setting the onchange property of the element.
By default, events created and dispatched like this don't propagate (bubble) up the DOM tree like events normally do.
If you want the event to bubble, you need to pass a second argument to the Event constructor:
var event = new Event('change', { bubbles: true });
Information about browser compability:
dispatchEvent()
Event()
In jQuery I mostly use:
$("#element").trigger("change");
ugh don't use eval for anything. Well, there are certain things, but they're extremely rare.
Rather, you would do this:
document.getElementById("test").onchange()
Look here for more options:
http://jehiah.cz/archive/firing-javascript-events-properly
For some reason ele.onchange() is throwing a "method not found" expception for me in IE on my page, so I ended up using this function from the link Kolten provided and calling fireEvent(ele, 'change'), which worked:
function fireEvent(element,event){
if (document.createEventObject){
// dispatch for IE
var evt = document.createEventObject();
return element.fireEvent('on'+event,evt)
}
else{
// dispatch for firefox + others
var evt = document.createEvent("HTMLEvents");
evt.initEvent(event, true, true ); // event type,bubbling,cancelable
return !element.dispatchEvent(evt);
}
}
I did however, create a test page that confirmed calling should onchange() work:
<input id="test1" name="test1" value="Hello" onchange="alert(this.value);"/>
<input type="button" onclick="document.getElementById('test1').onchange();" value="Say Hello"/>
Edit: The reason ele.onchange() didn't work was because I hadn't actually declared anything for the onchange event. But the fireEvent still works.
Taken from the bottom of QUnit
function triggerEvent( elem, type, event ) {
if ( $.browser.mozilla || $.browser.opera ) {
event = document.createEvent("MouseEvents");
event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView,
0, 0, 0, 0, 0, false, false, false, false, 0, null);
elem.dispatchEvent( event );
} else if ( $.browser.msie ) {
elem.fireEvent("on"+type);
}
}
You can, of course, replace the $.browser stuff to your own browser detection methods to make it jQuery independent.
To use this function:
var event;
triggerEvent(ele, "change", event);
This will basically fire the real DOM event as if something had actually changed.
This is the most correct answer for IE and Chrome::
var element = document.getElementById('xxxx');
var evt = document.createEvent('HTMLEvents');
evt.initEvent('change', false, true);
element.dispatchEvent(evt);
If you add all your events with this snippet of code:
//put this somewhere in your JavaScript:
HTMLElement.prototype.addEvent = function(event, callback){
if(!this.events)this.events = {};
if(!this.events[event]){
this.events[event] = [];
var element = this;
this['on'+event] = function(e){
var events = element.events[event];
for(var i=0;i<events.length;i++){
events[i](e||event);
}
}
}
this.events[event].push(callback);
}
//use like this:
element.addEvent('change', function(e){...});
then you can just use element.on<EVENTNAME>() where <EVENTNAME> is the name of your event, and that will call all events with <EVENTNAME>
The change event in an input element is triggered directly only by the user. To trigger the change event programmatically we need to dispatch the change event.
The question is Where and How?
"Where" we want the change event to be triggered exactly at the moment after a bunch of codes is executed, and "How" is in the form of the following syntax:
const myInput = document.getElementById("myInputId");
function myFunc() {
//some codes
myInput.dispatchEvent(new Event("change"));
}
In this way, we created the change event programmatically by using the Event constructor and dispatched it by the dispatchEvent() method. So whenever myFunc() method is invoked, after the //some codes are executed, our synthetic change event is immediately triggered on the desired input element.‍
Important result: Here, the change event is triggered by executing the //some codes in myFunc() instead of changing the input value by the user (default mode).
if you're using jQuery you would have:
$('#elementId').change(function() { alert('Do Stuff'); });
or MS AJAX:
$addHandler($get('elementId'), 'change', function(){ alert('Do Stuff'); });
Or in the raw HTML of the element:
<input type="text" onchange="alert('Do Stuff');" id="myElement" />
After re-reading the question I think I miss-read what was to be done. I've never found a way to update a DOM element in a manner which will force a change event, what you're best doing is having a separate event handler method, like this:
$addHandler($get('elementId'), 'change', elementChanged);
function elementChanged(){
alert('Do Stuff!');
}
function editElement(){
var el = $get('elementId');
el.value = 'something new';
elementChanged();
}
Since you're already writing a JavaScript method which will do the changing it's only 1 additional line to call.
Or, if you are using the Microsoft AJAX framework you can access all the event handlers via:
$get('elementId')._events
It'd allow you to do some reflection-style workings to find the right event handler(s) to fire.
Using JQuery you can do the following:
// for the element which uses ID
$("#id").trigger("change");
// for the element which uses class name
$(".class_name").trigger("change");
For triggering any event in Javascript.
document.getElementById("yourid").addEventListener("change", function({
//your code here
})

Categories