Bind custom event to JavaScript object? - javascript

I can't figure out how to do it. It would seem to be something like this:
function MyObject() {
this.fireEvent("myEvent");
}
And then in a separate JavaScript file:
var obj = new MyObject();
obj.addEventListener("myEvent", function() {
alert("Event Fired");
});
But of course it doesn't work. My question is, how would I go about doing something like that?

In your example, you're firing the event immediately in the constructor (before the event listener is attached). Try moving the firing logic into a separate function.
Update:
Also, it seems like you're not firing an event properly. See this article for more information on how to properly fire events in a cross-browser manner. From that article:
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);
}
}

Related

Get All Events that happened on a page

Is there a way to know all the events that happened on document in JavaScript, without going through them one by one?
Instead of running through all events and doing this:
document.onDocumentContentLoaded = function(e) {
documentLoaded = true
};
document.onmousewheel = function(e) {
mouseWheel = true;
};
Is there a function I can call last thing in a page that gives me an array of all events that were called on a certain DOM (document in this case)?
$(window).on("beforeunload", function() {
//var events = document.GetAllEvents();
});

How is the parameter involved in order to let function one "know" that it shall react to what happens in function two?

The following code actually works, but I don't understand why. How come that when I pass the "event"-parameter to the function zaehle(), the function actually "knows" that it is supposed to react on what happens in the setup function?
I just can't see what connnects the zaehle() and the setup() function or how the parameter that I pass to zaehle() would be involved.
I hope I could make the question clear. If not I'll gladly try to explain it somehow else. It really bugs me and I feel like I can't go on studying until I get it.
<body>
<div id="eins">0</div>
<div id="zwei">0</div>
<div id="drei">0</div>
<div id="vier">0</div>
<div id="funf">0</div>
</body>
JS
var mouseoverZaehler = 0;
function zaehle(event) {
mouseoverZaehler++;
event.target.innerHTML = mouseoverZaehler;
}
function setup() {
document.getElementById("eins").addEventListener("mouseover", zaehle);
document.getElementById("zwei").addEventListener("mouseover", zaehle);
document.getElementById("drei").addEventListener("mouseover", zaehle);
document.getElementById("vier").addEventListener("mouseover", zaehle);
document.getElementById("funf").addEventListener("mouseover", zaehle);
}
window.addEventListener("load", setup);
Here is what happens step by step:
Page loads
setup function is called (because of window.addEventListener("load", setup))
Each element in setup function gets a mouseover event listener attached to it and when it fires zaehle function is called (because of document.getElementById("number").addEventListener("mouseover", zaehle))
You move your mouse over any of the elements
zaehle function gets called - mouseoverZaehler is incremented and innerHTML of the targeted element is set to the updated value of mouseoverZaehler
Check out addEventListener docs for further details.
The addEventListener calls in your setup function tell the browser that when a mouseover event occurs on the relevant element, it should call the function you're giving it (zaehle, in your case). It's the browser that passes the argument to zaehle, later, when calling it.
You could imagine addEventListener, conceptually, as putting that handler function on a list for the event on the element:
// VERY conceptual, leaves out a lot of details
function addEventListener(eventName, handler) {
this.events[eventName].handlers.push(handler);
}
...and then later, when the event occurs, the browser creates an event object and calls those handlers:
// Again, VERY conceptual, leaves out a lot of details
var event = /*...*/;
element.events[eventName].handlers.forEach(function(handler) {
handler.call(element, event);
});
Here's a working analogue of what's going on:
function FakeElement () {
this.events = Object.create(null);
}
FakeElement.prototype.addEventListener = function(eventName, handler) {
var eventEntry = this.events[eventName];
if (!eventEntry) {
eventEntry = this.events[eventName] = {
handlers: []
};
}
eventEntry.handlers.push(handler);
};
FakeElement.prototype.trigger = function(eventName) {
var event = {type: eventName}; // "Browser" creates the event
var eventEntry = this.events[eventName];
var handlers = eventEntry && eventEntry.handlers;
if (handlers) {
handlers.forEach(function(handler) {
handler.call(this, event); // "Browser" calls handler, passing
}); // the event into it
}
};
// Using it:
function zaehle(event) {
console.log("zaehle got event: " + event.type);
}
var e = new FakeElement();
e.addEventListener("mouseover", zaehle);
console.log("added handler for mouseover to element");
// Simulate the event occurring
var timer = setInterval(function() {
e.trigger("mouseover");
}, 500);
setTimeout(function() {
clearInterval(timer);
}, 3000);
You have registered your callback/function zaehle() for mouseover event. So when that event occurs for a specific div, browser calls the callback with event object which contains information about the event and the target i.e event occurred on which element.

How to call my some script after to work out google tag manager?

I have google tag manager snippet in my header, he adds some arguments to my links. I wont parse this links AFTER work out this manager.
How do I do this?
For the moment I can start my function only with setTimeout, but I thing is not correct.
In this case, the manager does not work at all, nothing is displayed in the console.
This code is located in the header
What am I doing wrong?
nothing errors in console
I would create a Custom HTML tag in GTM that fires a JavaScript event that you can listen for.
<script>
window.dispatchEvent(new CustomEvent('gtm:loaded'))
</script>
Then, in your source code, listen for that event.
window.addEventListener('gtm:loaded', function (event) {
// give the necessary tag a chance to run
setTimeout(function () {
// your code
}, 500)
})
Note, you'll need to use a polyfill for CustomEvent if you want to support IE.
(function () {
if ( typeof window.CustomEvent === "function" ) return false;
function CustomEvent ( event, params ) {
params = params || { bubbles: false, cancelable: false, detail: undefined };
var evt = document.createEvent( 'CustomEvent' );
evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
return evt;
}
CustomEvent.prototype = window.Event.prototype;
window.CustomEvent = CustomEvent;
})();
source: https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent

Define the order of execution of functions after event in javascript

Just, before reading, I have read about this thread: Order of execution of functions bound to an event in Javascript but its not helping. Actually,
I have an anonymous function, define like that:
<input type="button" name="blablabla" value="Send" onclick="javascript:blablabla">
So, this function is on a button, use to validate forms. As you can see, It's an anonymous function, and I don't have any access on this code. This function start when I click on it. Okay, I have understood that
But, this function is not totally full, and I want to add my own, with her own logic of check. So I want my checks first, and then call the anonymous function. Here is my code:
function check() {
console.log("debut de check");
var participant = document.getElementById("new_participant_name");
var participant1 = document.getElementById("new_participant2_name");
var participant2 = document.getElementById("new_participant3_name");
participant = participant.value;
participant1 = participant1.value;
participant2 = participant2.value;
var trois_participants = (participant2) ? true : false;
if (!participant1 || !participant)
{
console.log("pas de participant1 ou participant, sert à rien de gérer la suite");
//if the script come here, I want to stop processing, and don't want to call the anonymous function.
return ;
}
}
window.onload = function()
{
document.getElementById("InsertButton").addEventListener('click', function () {
check();
})};
So, I want to call my function (check) before the anonymous function, but, with the same event. I don't know if I am totally understable... thanks per avance
EDIT: Sorry guys, My code have a bug before, yes the code is inlined, I will try all of your solutions tomorrow, thanks guys
If (and only if) the existing handler is attached using an inline onclick="..." handler, you can obtain its value, and then overwrite it:
window.onload = function() {
var el = document.getElementById('InsertButton');
var old_click = el.onclick;
el.onclick = undefined;
el.addEventListener('click', function() {
check();
old_click(this);
});
}
Why not create your own handler??
Element.prototype.myEventListener=function(name,func){
this.addEventListener(name,function(){
if(!check()){return;}
func();
});
};
Now you can do:
document.body.myEventListener("click",function(){
alert("t");
});
Check will always be called before the registered handler.
Note, to block the call, check must return false:
function check(){
return false;//no custom eventlistener fires
return true;//all will fire
}
Use the useCapture flag so you can intercept the event while it's travelling down to the button.
At that point you can perform your check, and if it fails you can call stopPropagation on the event to prevent it from reaching the handlers that are attached to its bubbling phase.
Also, by nature, events are quite bad at managing the order of execution. In general they depend on the order of registration of the listeners.
// code over which you have no control and can't change
var btn = document.getElementById("greeter");
btn.addEventListener("click", function() {
console.log("hello");
})
// code you can add later
function check() {
return Math.random() > 0.5;
}
window.addEventListener("click", function(e) {
var greeter = document.getElementById("greeter");
if (e.target === greeter && !check()) {
e.stopPropagation();
}
}, true)
<button id="greeter">hello world</button>

How to retrieve the `event` object if the DOMContentLoaded event has been triggered before setting a listener

Is there a way to retrieve the event object of the DOMContentLoaded event even if it has been triggered before setting an eventListener?
I have found some timing data for DOMContentLoaded and was hoping the event data might be stored as well.
window.performance.timing.domContentLoadedEventStart
window.performance.timing.domContentLoadedEventEnd
I would like to pass the event object to my callback whether it was called directly or as a result of the eventlistener.
var callback = function(event){
console.log(event)
}
if (document.readyState !== "loading") {
var event = window.DOMContentLoadedEvent; // doesnt exist
callback.call(this, event);
} else {
document.addEventListener('DOMContentLoaded', callback, false)
}
I suppose I could create a new object and return that but i would like my code a small as possible.
var event = {
srcElement: document,
target:document,
timeStamp:window.performance.timing.domContentLoadedEventEnd,
type:"DOMContentLoaded",
}
callback.call(this, event);
What I have done instead is to add another event listener which will definitely be registered before the DOMContentLoaded event if fired, the handler stores the event object;
document.addEventListener('DOMContentLoaded', function(event){
window.DOMContentLoadedEvent = event;
});
Edit
My code is a very simple domready function
document.addEventListener('DOMContentLoaded', function(event){
window.DOMContentLoadedEvent = event;
});
domready = function(callback) {
if (document.readyState === "loading") {
return document.addEventListener('DOMContentLoaded', callback, false);
}
return callback.call(this, window.DOMContentLoadedEvent);
}
The following code may reside in an external script an be inserted after the DOMContentLoaded event has fired.
domready(function(event){
console.log(event)
});
Am I able to retrieve the event data without setting up an additional event listener ?
check this:
<body>
...
<script>
var DOMevent; // global variable
document.addEventListener('DOMContentLoaded', function(event) {
DOMevent = event; // save it
}, false);
window.addEventListener('load', function () {
processEvent(DOMevent); // works fine
}, false);
function processEvent(e) {
console.log(e);
}
</script>
</body>
console.log(e); will show DOMevent.
more about readyState
https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState
more about DOMContentLoaded event
https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded
more about 'load' event
https://developer.mozilla.org/en-US/docs/Web/Events/load *typo in example! document -> window!

Categories