How to test window.addEventListener function - javascript

Here is an event listener added, if I want to test if this event listener is working or not, how do I test? window.postMessage doesn't seem to be triggering this event. Basically, how do I trigger "some_event" so that my EventListener runs?
window.addEventListener('some_event', function() {
console.log("some_event triggered");
});
Please note, I was able to reproduce with "click" event, but what I want to know is, how do I know if any string is passed as an event. Example:
window.addEventListener('add_to_cart', function() {
console.log("some_event triggered");
});
So I would like to simulate this event listener to check if it's working or not. How do I test this?

You need to use some concrete event name like for example click - and click on browser page window - eg:
window.addEventListener('click', function() {
console.log("some_event triggered");
});
Here is some info about events and situations when they are trigger.
After question update
Yes you can define and fire arbitrary events - read here. And here is some example code:
var event = new Event('some_event');
// Listen for the event.
window.addEventListener('some_event', function (e) {
console.log('some_event triggered')
}, false);
// Dispatch the event.
window.dispatchEvent(event);
So you fire event using window.dispatchEvent(event) and this is the way you can test it.

You can trigger an event using dispatchEvent and fireEvent in IE.
var ev, element = window;
if (document.createEvent) {
ev = document.createEvent("HTMLEvents");
ev.initEvent("eventname", true, true);
ev.eventName = "eventname";
element.dispatchEvent(ev);
} else {
ev = document.createEventObject();
ev.eventType = "eventname";
ev.eventName = "eventname";
element.fireEvent("on" + ev.eventType, event);
}
function triggerEvent(elem, name){
var ev;
if (document.createEvent) {
ev = document.createEvent("HTMLEvents");
ev.initEvent(name, true, true);
ev.eventName = name;
elem.dispatchEvent(ev);
} else {
ev = document.createEventObject();
ev.eventType = name;
ev.eventName = name;
elem.fireEvent("on" + ev.eventType, event);
}
}
window.addEventListener("click", function(e){
console.log("Clicked");
});
window.addEventListener("custom_event", function(e){
console.log("custom_event triggered");
});
triggerEvent(window, "click");
triggerEvent(window, "custom_event");

Related

I just started codeing and i need some help reagarding my assignment in javascript

When left-clicking anywhere on the page, "B" should change to "click"
function change_text(){
var p2 = document.getElementById("p2").value;
document.getElementById("p2").innerHTML = "click";
}
in HTML
<body onload="change_text()">
In your JS file
function change_text(){
const p2 = document.getElementById("p2");
document.addEventListener('click', function () {
p2.innerHTML = 'click'
})
}
You could use an Listener 'mouseup' (after click) or 'mousedown' (as soon as the button is pressed)
The capture and passive down there will make more faster, it's a garantee that you will not stop normal click events in your function.
window.addEventListener('mousedown', function (){
document.getElementById("p2").innerHTML = "click";
}, {
capture: true,
passive: true
})

What is the JavaScript equivalent of JQuery's .change(); [duplicate]

I have attached an event to a text box using addEventListener. It works fine. My problem arose when I wanted to trigger the event programmatically from another function.
How can I do it?
Note: the initEvent method is now deprecated. Other answers feature up-to-date and recommended practice.
You can use fireEvent on IE 8 or lower, and W3C's dispatchEvent on most other browsers. To create the event you want to fire, you can use either createEvent or createEventObject depending on the browser.
Here is a self-explanatory piece of code (from prototype) that fires an event dataavailable on an element:
var event; // The custom event that will be created
if(document.createEvent){
event = document.createEvent("HTMLEvents");
event.initEvent("dataavailable", true, true);
event.eventName = "dataavailable";
element.dispatchEvent(event);
} else {
event = document.createEventObject();
event.eventName = "dataavailable";
event.eventType = "dataavailable";
element.fireEvent("on" + event.eventType, event);
}
A working example:
// Add an event listener
document.addEventListener("name-of-event", function(e) {
console.log(e.detail); // Prints "Example of an event"
});
// Create the event
var event = new CustomEvent("name-of-event", { "detail": "Example of an event" });
// Dispatch/Trigger/Fire the event
document.dispatchEvent(event);
For older browsers polyfill and more complex examples, see MDN docs.
See support tables for EventTarget.dispatchEvent and CustomEvent.
If you don't want to use jQuery and aren't especially concerned about backwards compatibility, just use:
let element = document.getElementById(id);
element.dispatchEvent(new Event("change")); // or whatever the event type might be
See the documentation here and here.
EDIT: Depending on your setup you might want to add bubbles: true:
let element = document.getElementById(id);
element.dispatchEvent(new Event('change', { 'bubbles': true }));
if you use jQuery, you can simple do
$('#yourElement').trigger('customEventName', [arg0, arg1, ..., argN]);
and handle it with
$('#yourElement').on('customEventName',
function (objectEvent, [arg0, arg1, ..., argN]){
alert ("customEventName");
});
where "[arg0, arg1, ..., argN]" means that these args are optional.
Note: the initCustomEvent method is now deprecated. Other answers feature up-to-date and recommended practice.
If you are supporting IE9+ the you can use the following. The same concept is incorporated in You Might Not Need jQuery.
function addEventListener(el, eventName, handler) {
if (el.addEventListener) {
el.addEventListener(eventName, handler);
} else {
el.attachEvent('on' + eventName, function() {
handler.call(el);
});
}
}
function triggerEvent(el, eventName, options) {
var event;
if (window.CustomEvent) {
event = new CustomEvent(eventName, options);
} else {
event = document.createEvent('CustomEvent');
event.initCustomEvent(eventName, true, true, options);
}
el.dispatchEvent(event);
}
// Add an event listener.
addEventListener(document, 'customChangeEvent', function(e) {
document.body.innerHTML = e.detail;
});
// Trigger the event.
triggerEvent(document, 'customChangeEvent', {
detail: 'Display on trigger...'
});
If you are already using jQuery, here is the jQuery version of the code above.
$(function() {
// Add an event listener.
$(document).on('customChangeEvent', function(e, opts) {
$('body').html(opts.detail);
});
// Trigger the event.
$(document).trigger('customChangeEvent', {
detail: 'Display on trigger...'
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
I searched for firing click, mousedown and mouseup event on mouseover using JavaScript. I found an answer provided by Juan Mendes. For the answer click here.
Click here is the live demo and below is the code:
function fireEvent(node, eventName) {
// Make sure we use the ownerDocument from the provided node to avoid cross-window problems
var doc;
if (node.ownerDocument) {
doc = node.ownerDocument;
} else if (node.nodeType == 9) {
// the node may be the document itself, nodeType 9 = DOCUMENT_NODE
doc = node;
} else {
throw new Error("Invalid node passed to fireEvent: " + node.id);
}
if (node.dispatchEvent) {
// Gecko-style approach (now the standard) takes more work
var eventClass = "";
// Different events have different event classes.
// If this switch statement can't map an eventName to an eventClass,
// the event firing is going to fail.
switch (eventName) {
case "click": // Dispatching of 'click' appears to not work correctly in Safari. Use 'mousedown' or 'mouseup' instead.
case "mousedown":
case "mouseup":
eventClass = "MouseEvents";
break;
case "focus":
case "change":
case "blur":
case "select":
eventClass = "HTMLEvents";
break;
default:
throw "fireEvent: Couldn't find an event class for event '" + eventName + "'.";
break;
}
var event = doc.createEvent(eventClass);
var bubbles = eventName == "change" ? false : true;
event.initEvent(eventName, bubbles, true); // All events created as bubbling and cancelable.
event.synthetic = true; // allow detection of synthetic events
// The second parameter says go ahead with the default action
node.dispatchEvent(event, true);
} else if (node.fireEvent) {
// IE-old school style
var event = doc.createEventObject();
event.synthetic = true; // allow detection of synthetic events
node.fireEvent("on" + eventName, event);
}
};
The accepted answer didn’t work for me, none of the createEvent ones did.
What worked for me in the end was:
targetElement.dispatchEvent(
new MouseEvent('click', {
bubbles: true,
cancelable: true,
view: window,
}));
Here’s a snippet:
const clickBtn = document.querySelector('.clickme');
const viaBtn = document.querySelector('.viame');
viaBtn.addEventListener('click', function(event) {
clickBtn.dispatchEvent(
new MouseEvent('click', {
bubbles: true,
cancelable: true,
view: window,
}));
});
clickBtn.addEventListener('click', function(event) {
console.warn(`I was accessed via the other button! A ${event.type} occurred!`);
});
<button class="clickme">Click me</button>
<button class="viame">Via me</button>
From reading:
https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent
Modified #Dorian's answer to work with IE:
document.addEventListener("my_event", function(e) {
console.log(e.detail);
});
var detail = 'Event fired';
try {
// For modern browsers except IE:
var event = new CustomEvent('my_event', {detail:detail});
} catch(err) {
// If IE 11 (or 10 or 9...?) do it this way:
// Create the event.
var event = document.createEvent('Event');
// Define that the event name is 'build'.
event.initEvent('my_event', true, true);
event.detail = detail;
}
// Dispatch/Trigger/Fire the event
document.dispatchEvent(event);
FIDDLE: https://jsfiddle.net/z6zom9d0/1/
SEE ALSO:
https://caniuse.com/#feat=customevent
Just to suggest an alternative that does not involve the need to manually invoke a listener event:
Whatever your event listener does, move it into a function and call that function from the event listener.
Then, you can also call that function anywhere else that you need to accomplish the same thing that the event does when it fires.
I find this less "code intensive" and easier to read.
I just used the following (seems to be much simpler):
element.blur();
element.focus();
In this case the event is triggered only if value was really changed just as you would trigger it by normal focus locus lost performed by user.
function fireMouseEvent(obj, evtName) {
if (obj.dispatchEvent) {
//var event = new Event(evtName);
var event = document.createEvent("MouseEvents");
event.initMouseEvent(evtName, true, true, window,
0, 0, 0, 0, 0, false, false, false, false, 0, null);
obj.dispatchEvent(event);
} else if (obj.fireEvent) {
event = document.createEventObject();
event.button = 1;
obj.fireEvent("on" + evtName, event);
obj.fireEvent(evtName);
} else {
obj[evtName]();
}
}
var obj = document.getElementById("......");
fireMouseEvent(obj, "click");
You could use this function i compiled together.
if (!Element.prototype.trigger)
{
Element.prototype.trigger = function(event)
{
var ev;
try
{
if (this.dispatchEvent && CustomEvent)
{
ev = new CustomEvent(event, {detail : event + ' fired!'});
this.dispatchEvent(ev);
}
else
{
throw "CustomEvent Not supported";
}
}
catch(e)
{
if (document.createEvent)
{
ev = document.createEvent('HTMLEvents');
ev.initEvent(event, true, true);
this.dispatchEvent(event);
}
else
{
ev = document.createEventObject();
ev.eventType = event;
this.fireEvent('on'+event.eventType, event);
}
}
}
}
Trigger an event below:
var dest = document.querySelector('#mapbox-directions-destination-input');
dest.trigger('focus');
Watch Event:
dest.addEventListener('focus', function(e){
console.log(e);
});
Hope this helps!
You can use below code to fire event using Element method:
if (!Element.prototype.triggerEvent) {
Element.prototype.triggerEvent = function (eventName) {
var event;
if (document.createEvent) {
event = document.createEvent("HTMLEvents");
event.initEvent(eventName, true, true);
} else {
event = document.createEventObject();
event.eventType = eventName;
}
event.eventName = eventName;
if (document.createEvent) {
this.dispatchEvent(event);
} else {
this.fireEvent("on" + event.eventType, event);
}
};
}
if (!Element.prototype.triggerEvent) {
Element.prototype.triggerEvent = function (eventName) {
var event;
if (document.createEvent) {
event = document.createEvent("HTMLEvents");
event.initEvent(eventName, true, true);
} else {
event = document.createEventObject();
event.eventType = eventName;
}
event.eventName = eventName;
if (document.createEvent) {
this.dispatchEvent(event);
} else {
this.fireEvent("on" + event.eventType, event);
}
};
}
var input = document.getElementById("my_input");
var button = document.getElementById("my_button");
input.addEventListener('change', function (e) {
alert('change event fired');
});
button.addEventListener('click', function (e) {
input.value = "Bye World";
input.triggerEvent("change");
});
<input id="my_input" type="input" value="Hellow World">
<button id="my_button">Change Input</button>
What's worth noticing, is the fact that we can create, any kind of pre-defined events, and listen to it from anywhere.
We are not limited to classical built-in events.
In this base example, a custom event interfacebuiltsuccessuserdefinedevent is dispatched every 3 seconds, on the self.document
self.document.addEventListener('interfacebuiltsuccessuserdefinedevent', () => console.log("WOW"), false)
setInterval(() => { // Test
self.document.dispatchEvent(new Event('interfacebuiltsuccessuserdefinedevent'))
}, 3000 ) // Test
Interesting fact: elements can listen for events that haven't been created yet.
The most efficient way is to call the very same function that has been registered with addEventListener directly.
You can also trigger a fake event with CustomEvent and co.
Finally some elements such as <input type="file"> support a .click() method.
var btn = document.getElementById('btn-test');
var event = new Event(null);
event.initEvent('beforeinstallprompt', true, true);
btn.addEventListener('beforeinstallprompt', null, false);
btn.dispatchEvent(event);
this will imediattely trigger an event 'beforeinstallprompt'
HTML
myLink
<button onclick="fireLink(event)"> Call My Link </button>
JS
// click event listener of the link element --------------
document.getElementById('myLink').addEventListener("click", callLink);
function callLink(e) {
// code to fire
}
// function invoked by the button element ----------------
function fireLink(event) {
document.getElementById('myLink').click(); // script calls the "click" event of the link element
}
Use jquery event call.
Write the below line where you want to trigger onChange of any element.
$("#element_id").change();
element_id is the ID of the element whose onChange you want to trigger.
Avoid the use of
element.fireEvent("onchange");
Because it has very less support. Refer this document for its support.
What you want is something like this:
document.getElementByClassName("example").click();
Using jQuery, it would be something like this:
$(".example").trigger("click");

Event handler isn't working

I have one input which have event listener onblur and button which have event listener onclick.
This is how I organized it
document.addEventListener("DOMContentLoaded", function() {
window.searchButton = document.getElementById("searchButton");
window.searchInput = document.getElementById("searchInput");
searchInput.onfocus = searchFocus;
searchInput.onblur = searchBlur;
searchButton.onclick = search;
});
var resize = function(self, newSize) {
self.setAttribute("size", newSize);
};
var searchFocus = function() {
event.stopPropagation();
resize(searchInput, 30);
};
var searchBlur = function() {
if (searchInput.value === "") {
resize(searchInput, 10);
}
};
var search = function() {
event.stopPropagation();
};
But when the input is focused and I am clicking on the button, working onblur function, but onclick function isn't working. Why and how can I fix that?
Your search callback should have event in its param list. Same is true for searchFocus
var search = function(event){
event.stopPropagation();
};
Also, you might want to check that your DOMContentLoaded handler is firing. Depending upon how your scripts are organized/loaded, it is possible that the DOM has already loaded and that event fired before you register the handler. That's a common oversight.
How to detect if DOMContentLoaded was fired

removeEventListener from body not working

I'm trying to remove an event listener after a function has been called. But the event listener for "keyup" stays attached to the body, no matter what I try. What is wrong with the code?
function displayImage() {
//this is a simplified version of the code
var outerFrame = document.createElement('div');
outerFrame.className = 'popup-outer';
document.body.appendChild(outerFrame);
document.body.addEventListener('keyup', hideImage.bind(outerFrame), false);
}
function hideImage(e) {
if (e.keyCode === 27) {
// this doesn't work, it stays attached to the body element
document.body.removeEventListener('keyup', hideImage, false);
document.body.removeChild(this);
}
e.preventDefault();
}
It's because technically
hideImage.bind(outerFrame)
is different from
hideImage
because the first one returns a copy of the function hideImage.
So when you try to unbind hideImage, the event manager does not find it because it registred a copy of it and thus nothing is removed :-/.
EDIT :
In your case, I guess you have no other choice but keeping track of your listeners. I went ahead and made this quickly, it should fix your problem.
var listeners = {};
function createDiv() {
var outerFrame = document.createElement('div');
outerFrame.className = 'popup-outer';
return outerFrame;
}
function displayImage() {
var div = createDiv();
bindEvent(div);
document.body.appendChild(div);
}
function bindEvent(el) {
var handler = function(e) {
hideImg.call(el, e);
}
listeners[el] = handler;
document.body.addEventListener('keyup', handler, false);
}
function hideImg(e) {
if (e.keyCode === 27) {
// listeners[this] refers to the "private" handler variable we created in the bindEvent function
document.body.removeEventListener('keyup', listeners[this], false);
delete listeners[this];
document.body.removeChild(this);
}
}

How to trigger JavaScript custom events correctly

I am struggling to understand how a custom event type is linked to a specific user action/trigger. All documentation seems to dispatch the event without any user interaction.
In the following example I want the event to be dispatched once a user has been hovering on the element for 3 seconds.
var img = document.createElement('img');img.src = 'http://placehold.it/100x100';
document.body.appendChild(img)
var event = new CustomEvent("hoveredforthreeseconds");
img.addEventListener('hoveredforthreeseconds', function(e) { console.log(e.type)}, true);
var thetrigger = function (element, event) {
var timeout = null;
element.addEventListener('mouseover',function() {
timeout = setTimeout(element.dispatchEvent(event), 3000);
},true);
element.addEventListener('mouseout', function() {
clearTimeout(timeout);
},true);
};
I have a trigger but no logical way of connecting it to the event.
I was thinking about creating an object called CustomEventTrigger which is essentially CustomEvent but has a third parameter for the trigger and also creating a method called addCustomEventListener, which works the same as addEventListener but when initialised it then passes the target Element to the custom event trigger which then dispatches the event when it's instructed to.
Custom events have to be triggered programatically through dispatchEvent, they are not fired by the DOM. You will always need to explictly call them in your code, such as in response to a user-generated event such as onmouseover, or a change of state such as onload.
You're very close to a working implementation, however you're immediately invoking dispatchEvent in your setTimeout. If you save it into a closure (as below) you can invoke dispatchEvent while passing your element after setTimeout has finished the timeout.
It's also good practice to declare your variables at the top of a file, to avoid possible scope issues.
var img = document.createElement('img'), timeout, event, thetrigger;
img.src = 'http://placehold.it/100x100';
document.body.appendChild(img);
img.addEventListener("hoveredForThreeSeconds", afterHover, false);
thetrigger = function (element, event) {
timeout = null;
element.addEventListener('mouseover',function() {
timeout = setTimeout(function(){ element.dispatchEvent(event) }, 3000);
},true);
element.addEventListener('mouseout', function() {
clearTimeout(timeout);
},true);
};
function afterHover(e) {
console.log("Event is called: " + e.type);
}
event = new CustomEvent("hoveredForThreeSeconds");
thetrigger(img, event);
I have created a method called addCustomEventListener, which works the same as addEventListener but when initialised passes the target Element to the custom event trigger which dispatches the event when it says, so in this case it only dispatches if the timeout reaches 3 seconds.
var img = document.getElementById('img');
window.mouseover3000 = new CustomEvent('mouseover3000', {
detail: {
trigger: function(element, type) {
timeout = null;
element.addEventListener('mouseover', function() {
timeout = setTimeout(function() {
element.dispatchEvent(window[type])
}, 3000);
}, false);
element.addEventListener('mouseout', function() {
clearTimeout(timeout);
}, false)
}
}
});
window.tripleclick = new CustomEvent('tripleclick', {
detail: {
trigger: function(element, type) {
element.addEventListener('click', function(e) {
if(e.detail ===3){
element.dispatchEvent(window[type])
}
}, false);
}
}
});
EventTarget.prototype.addCustomEventListener = function(type, listener, useCapture, wantsUntrusted) {
this.addEventListener(type, listener, useCapture, wantsUntrusted);
window[type].detail.trigger(this, type);
}
var eventTypeImage = function(e) {
this.src = "http://placehold.it/200x200?text=" + e.type;
}
img.addEventListener('mouseout', eventTypeImage, false);
img.addEventListener('mouseover', eventTypeImage, false);
img.addCustomEventListener('mouseover3000', eventTypeImage, false);
img.addCustomEventListener('tripleclick', eventTypeImage, false);
<img id="img" src="http://placehold.it/200x200?text=No+hover" ;/>
I think this could be useful to others so please feel free to improve on this.

Categories

Resources