confusion regarding event handling in Javascript - javascript

I am new to Javascript. while practicing i encounter a code regarding event handling. Here is the code
//This generic event handler creates an object called eventHandler
var etHandler = {};
if (document.addEventListener) {
//eventHandler object has two methods added to it, add()and remove(),
etHandler.add = function(element, eventType, eventFunction) {
/**
* The add method in each model determines whether the event type is a load event, meaning that
* the function needs to be executed on page load.
*/
if (eventType == "load") {
.......
}
};// end of eventHandler.add = function()
etHandler.remove = function(element, eventType, eventFunction) {
element.detachEvent("on" + eventType, eventFunction);
}; //end of etHandler.remove = function()
}
function sendAlert() {
alert("Hello");
} //end of sendAlert()
function startTimer() {
var timerID = window.setTimeout(sendAlert,3000);
}//end of startTimer()
var mainBody = document.getElementById("mainBody");
etHandler.add(mainBody, "load", function() {
startTimer();
}
);
The questions that i want to ask are this. We create an empty object.var etHandler = {};. It's fine. Then we are checking condition if (document.addEventListener) {}. we didn't add any event listener to the document, but this condition is true. Why this condition is returning true?
Then we write etHandler.add = function(element, eventType, eventFunction) {}. Why we are writing etHandler.add? etHandler object has no property, when we created it. It's a null object. If we create etHandler like this
var etHandler = {
add: function() {
},
remove: function(){
}
};
Then we can write etHandler.add. The same question is for etHandler.remove also.
Thanks

The call if (document.addEventListener) is checking whether the browser supports this method. It is checking to see whether it exists on the document object. This is called feature detection and is frequently used to detect differences between browsers.
The call etHandler.add = function(element, eventType, eventFunction) defines the add method and creates it simultaneously. It is basically the same as in your example.

Related

How to delete listener with anonymous function? [duplicate]

I have an object that has methods in it. These methods are put into the object inside an anonymous function. It looks like this:
var t = {};
window.document.addEventListener("keydown", function(e) {
t.scroll = function(x, y) {
window.scrollBy(x, y);
};
t.scrollTo = function(x, y) {
window.scrollTo(x, y);
};
});
(there is a lot more code, but this is enough to show the problem)
Now I want to stop the event listener in some cases. Therefore I am trying to do a removeEventListener but I can't figure out how to do this. I have read in other questions that it is not possible to call removeEventListener on anonymous functions, but is this also the case in this situation?
I have a method in t created inside the anonymous function and therefore I thought it was possible. Looks like this:
t.disable = function() {
window.document.removeEventListener("keydown", this, false);
}
Why can't I do this?
Is there any other (good) way to do this?
Bonus info; this only has to work in Safari, hence the missing IE support.
You can name the function passed and use the name in the removeEventListener. as in:
button.addEventListener('click', function eventHandler() {
///this will execute only once
alert('only once!');
this.removeEventListener('click', eventHandler);
});
EDIT:
This will not work if you are working in strict mode ("use strict";)
EDIT 2:
arguments.callee is now deprecated (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments/callee)
I believe that is the point of an anonymous function, it lacks a name or a way to reference it.
If I were you I would just create a named function, or put it in a variable so you have a reference to it.
var t = {};
var handler = function(e) {
t.scroll = function(x, y) {
window.scrollBy(x, y);
};
t.scrollTo = function(x, y) {
window.scrollTo(x, y);
};
};
window.document.addEventListener("keydown", handler);
You can then remove it by
window.document.removeEventListener("keydown", handler);
A version of Otto Nascarella's solution that works in strict mode is:
button.addEventListener('click', function handler() {
///this will execute only once
alert('only once!');
this.removeEventListener('click', handler);
});
in modern browsers you can do the following...
button.addEventListener( 'click', () => {
alert( 'only once!' );
}, { once: true } );
https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Parameters
window.document.removeEventListener("keydown", getEventListeners(window.document.keydown[0].listener));
May be several anonymous functions, keydown1
Warning: only works in Chrome Dev Tools & cannot be used in code: link
There's a new way to do this that is supported by the latest versions of most popular browsers with the exception of Safari.
Check caniuse for updated support.
Update: Now also supported by Sefari (version 15^).
We can add an option to addEventListner called signal and assign a signal from an AbortController on which you can later call the abort() method.
Here is an example.
We create an AbortController:
const controller = new AbortController();
Then we create the eventListner and pass in the option signal:
document.addEventListener('scroll',()=>{
// do something
},{signal: controller.signal})
And then to remove the eventListner at a later time, we call:
controller.abort()
This is not ideal as it removes all, but might work for your needs:
z = document.querySelector('video');
z.parentNode.replaceChild(z.cloneNode(1), z);
Cloning a node copies all of its attributes and their values, including
intrinsic (in–line) listeners. It does not copy event listeners added using
addEventListener()
Node.cloneNode()
A not so anonymous option
element.funky = function() {
console.log("Click!");
};
element.funky.type = "click";
element.funky.capt = false;
element.addEventListener(element.funky.type, element.funky, element.funky.capt);
// blah blah blah
element.removeEventListener(element.funky.type, element.funky, element.funky.capt);
Since receiving feedback from Andy (quite right, but as with many examples, I wished to show a contextual expansion of the idea), here's a less complicated exposition:
<script id="konami" type="text/javascript" async>
var konami = {
ptrn: "38,38,40,40,37,39,37,39,66,65",
kl: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
};
document.body.addEventListener( "keyup", function knm ( evt ) {
konami.kl = konami.kl.slice( -9 );
konami.kl.push( evt.keyCode );
if ( konami.ptrn === konami.kl.join() ) {
evt.target.removeEventListener( "keyup", knm, false );
/* Although at this point we wish to remove a listener
we could easily have had multiple "keyup" listeners
each triggering different functions, so we MUST
say which function we no longer wish to trigger
rather than which listener we wish to remove.
Normal scoping will apply to where we can mention this function
and thus, where we can remove the listener set to trigger it. */
document.body.classList.add( "konami" );
}
}, false );
document.body.removeChild( document.getElementById( "konami" ) );
</script>
This allows an effectively anonymous function structure, avoids the use of the practically deprecated callee, and allows easy removal.
Incidentally: The removal of the script element immediately after setting the listener is a cute trick for hiding code one would prefer wasn't starkly obvious to prying eyes (would spoil the surprise ;-)
So the method (more simply) is:
element.addEventListener( action, function name () {
doSomething();
element.removeEventListener( action, name, capture );
}, capture );
To give a more up-to-date approach to this:
//one-time fire
element.addEventListener('mousedown', {
handleEvent: function (evt) {
element.removeEventListener(evt.type, this, false);
}
}, false);
JavaScript: addEventListener
method registers the specified listener on the EventTarget(Element|document|Window) it's called on.
EventTarget.addEventListener(event_type, handler_function, Bubbling|Capturing);
Mouse, Keyboard events Example test in WebConsole:
var keyboard = function(e) {
console.log('Key_Down Code : ' + e.keyCode);
};
var mouseSimple = function(e) {
var element = e.srcElement || e.target;
var tagName = element.tagName || element.relatedTarget;
console.log('Mouse Over TagName : ' + tagName);
};
var mouseComplex = function(e) {
console.log('Mouse Click Code : ' + e.button);
}
window.document.addEventListener('keydown', keyboard, false);
window.document.addEventListener('mouseover', mouseSimple, false);
window.document.addEventListener('click', mouseComplex, false);
removeEventListener
method removes the event listener previously registered with EventTarget.addEventListener().
window.document.removeEventListener('keydown', keyboard, false);
window.document.removeEventListener('mouseover', mouseSimple, false);
window.document.removeEventListener('click', mouseComplex, false);
caniuse
I have stumbled across the same problem and this was the best solution I could get:
/*Adding the event listener (the 'mousemove' event, in this specific case)*/
element.onmousemove = function(event) {
/*do your stuff*/
};
/*Removing the event listener*/
element.onmousemove = null;
Please keep in mind I have only tested this for the window element and for the 'mousemove' event, so there could be some problems with this approach.
Possibly not the best solution in terms of what you are asking. I have still not determined an efficient method for removing anonymous function declared inline with the event listener invocation.
I personally use a variable to store the <target> and declare the function outside of the event listener invocation eg:
const target = document.querySelector('<identifier>');
function myFunc(event) {
function code;
}
target.addEventListener('click', myFunc);
Then to remove the listener:
target.removeEventListener('click', myFunc);
Not the top recommendation you will receive but to remove anonymous functions the only solution I have found useful is to remove then replace the HTML element. I am sure there must be a better vanilla JS method but I haven't seen it yet.
I know this is a fairly old thread, but thought I might put in my two cents for those who find it useful.
The script (apologies about the uncreative method names):
window.Listener = {
_Active: [],
remove: function(attached, on, callback, capture){
for(var i = 0; i < this._Active.length; i++){
var current = this._Active[i];
if(current[0] === attached && current[1] === on && current[2] === callback){
attached.removeEventListener(on, callback, (capture || false));
return this._Active.splice(i, 1);
}
}
}, removeAtIndex(i){
if(this._Active[i]){
var remove = this._Active[i];
var attached = remove[0], on = remove[1], callback = remove[2];
attached.removeEventListener(on, callback, false);
return this._Active.splice(i, 1);
}
}, purge: function(){
for(var i = 0; i < this._Active.length; i++){
var current = this._Active[i];
current[0].removeEventListener(current[1], current[2]);
this._Active.splice(i, 1);
}
}, declare: function(attached, on, callback, capture){
attached.addEventListener(on, callback, (capture || false));
if(this._Active.push([attached, on, callback])){
return this._Active.length - 1;
}
}
};
And you can use it like so:
// declare a new onclick listener attached to the document
var clickListener = Listener.declare(document, "click" function(e){
// on click, remove the listener and log the clicked element
console.log(e.target);
Listener.removeAtIndex(clickListener);
});
// completely remove all active listeners
// (at least, ones declared via the Listener object)
Listener.purge();
// works exactly like removeEventListener
Listener.remove(element, on, callback);
I just experienced similiar problem with copy-protection wordpress plugin. The code was:
function disableSelection(target){
if (typeof target.onselectstart!="undefined") //For IE
target.onselectstart=function(){return false}
else if (typeof target.style.MozUserSelect!="undefined") //For Firefox
target.style.MozUserSelect="none"
else //All other route (For Opera)
target.onmousedown=function(){return false}
target.style.cursor = "default"
}
And then it was initiated by loosely put
<script type="text/javascript">disableSelection(document.body)</script>.
I came around this simply by attaching other annonymous function to this event:
document.body.onselectstart = function() { return true; };
Set anonymous listener:
document.getElementById('ID').addEventListener('click', () => { alert('Hi'); });
Remove anonymous listener:
document.getElementById('ID').removeEventListener('click',getEventListeners(document.getElementById('ID')).click[0].listener)
Using the AbortController, neat and clean
Attaching EventListener
const el = document.getElementById('ID')
const controller = new AbortController;
el.addEventListener('click',() => {
console.log("Clicked")
},{signal: controller.signal})
when you want to remove the event listener
controller.abort()
Another alternative workaround to achieve this is adding an empty event handler and preventing event propagation.
Let's assume you need to remove mouseleave event handler from an element which has #specific-div id, that is added with an anonymous function, and you can't use removeEventListener() since you don't have a function name.
You can add another event handler to that element and use event.stopImmediatePropagation(), for being sure this event handler works before existing ones you should pass the third parameter (useCapture) as true.
The final code should look like the below:
document.getElementById("specific-div")
.addEventListener("mouseleave", function(event) {
event.stopImmediatePropagation()
}, true);
This could help for some specific cases that you can't prefer cloneNode() method.
window.document.onkeydown = function(){};

Removing child-function event listeners

In building an extended input field (a complex date picker), I need to use two key event listeners. One is attached to the input field, and launches the interface. This is easy.
The second is attached to document, in order to close the complex overlay. Click on the overlay, and it does nothing. Click outside: the overlay disappears and the input field's value is updated.
It also needs to remove the event listener from the document.
This would all be straightforward… if it weren't based on object structures. I am not calling a stand-alone function. I am calling a child function of the data object associated with the field (which the field then has no way of referencing back to).
__DateField.prototype.activate = function () {
…
var t = this;
window.setTimeout(function () { document.addEventListener("click", function (ev) { t.closeDateSelector(ev) }, false); }, 0);
…
}
(I haven't figured out why that event attachment needs to be nested within the setTimeout, but if I don''t do it that way, it calls itself immediately.)
Anyhow, the problem is then that I cannot successfully call document.removeEventListener() because I it's not the same initial function.
Also, I can't approach it by attaching the function as a stand-alone, because I need the reference to the related __DateField object.
How can I remove that function from document?
I have looked at the various threads that say there is no way to inspect event listeners added via 'addEventListener`, though wonder if they may be out of date, as Firebug can list them…
To remove it, you must have a reference to the function, so the question boils down to: How can I keep a reference to the function?
The simplest answer, since you already have an object handy, is a property on the object, if you can rely on this being correct as of when you do the removal:
__DateField.prototype.activate = function () {
// …
var t = this;
window.setTimeout(function () {
t.listener = function (ev) {
t.closeDateSelector(ev)
};
document.addEventListener("click", listener, false);
}, 0);
// …
};
// To remove
__DateField.prototype.deactivate = function() {
if (this.listener != null) {
document.removeEventListener("click", this.listener, false);
this.listener = null;
}
};
Or if that's a problem for some reason, you could use a variable in a scoping function:
(function() {
var listener = null;
__DateField.prototype.activate = function () {
// …
var t = this;
window.setTimeout(function () {
listener = function (ev) {
t.closeDateSelector(ev)
};
document.addEventListener("click", listener, false);
}, 0);
// …
};
// Later, when removing
function removeIt() {
if (listener != null) {
document.removeEventListener("click", listener, false);
listener = null;
}
}
})();

js:scope of this inside an object on keypress event

Here is my JS simple script:
var Chat = function() {
console.log("init");
this.debug = function (txt) {
console.log(txt);
}
document.getElementById('shoutBoxInput').addEventListener("keypress", keyPressedFunction, false);
this.keyPressedFunction = function(e){
console.log("keyPressed");
}
this.sendText = function() {
var texte = document.getElementById('shoutBoxInput').value;
if (texte=="") return;
document.getElementById('shoutBoxInput').value =""
this.debug("sendTexte:"+texte);
}
this.receiveText = function(username, texte) {
}
}
var chat = new Chat();
My problem comes from:
document.getElementById('shoutBoxInput').addEventListener("keypress", keyPressedFunction, false);
this.keyPressedFunction = function(e){
Error Uncaught ReferenceError: keyPressedFunction is not defined
If I use:
document.getElementById('shoutBoxInput').addEventListener("keydown", this.keyPressedFunction, true);
then keyPressedFunction is never called.
Fiddle: http://jsfiddle.net/ghLfhb6z/
Let's start with the problem, and then move to what's dangerous about your code.
The problem is that when you call addEventListener, this.keyPressedEvent doesn't yet exist:
// this.keyPressedFunction doesn't exist...so you are registering a 'keypress'
// event to undefined.
document.getElementById('shoutBoxInput').addEventListener("keypress",
keyPressedFunction, false);
// now you define this.keyPressedFunction
this.keyPressedFunction = function(e){
console.log("keyPressed");
}
// so this is where you should be attaching it to the event
You may be thinking about JavaScript's hosting mechanism, and thinking "ah, the this.keyPressedFunction definition is being hoisted to the top of this function, so it's available for assigment." But hoisting only applies to variable and function definitions; what you're doing is assigning an anonymous function to a member property, so hoisting does not apply.
Now on to the dangerous:
When you use a method (a function property of an object) for a callback, the meaning of this is lost when that callback is invoked. (I know you aren't currently using this in your callback, but you probably will eventually!) In other words, when a key is pressed, and keyPressedFunction is called, the value of this won't be what you expect. The upshot of this is you have to be very careful assigning methods to callbacks or events. If you want to do it, you'll have to use Function.prototype.bind. Here's your code re-written in the correct order, and using bind:
this.keyPressedFunction = function(e){
console.log("keyPressed");
}
document.getElementById('shoutBoxInput').addEventListener("keypress",
this.keyPressedFunction.bind(this), false);
place your function before you use its referenc...then use this.keyPressedFunction...then is 'keypress' a valid native js event ?
http://jsfiddle.net/ghLfhb6z/4/
yes there was the errors I told, in fact most important is to place your event handlers at the end, check the right event, and use this if the function is on this :
var Chat = function() {
console.log("init");
this.debug = function (txt) {
console.log(txt);
}
this.keyPressedFunction = function(e){
console.log("keyPressed");
}
this.sendText = function() {
var texte = document.getElementById('shoutBoxInput').value;
if (texte=="") return;
document.getElementById('shoutBoxInput').value =""
this.debug("sendTexte:"+texte);
}
this.receiveText = function(username, texte) {
}
// place this at the end
document.getElementById('shoutBoxInput').addEventListener("keydown", this.keyPressedFunction, false);
}
var chat = new Chat();
#dmidz has provided a correct answer that will solve your problem, but if your keyPressedFunction only needs to be referred to code inside your Chat() module, then you don't need to make them properties of this (Chat):
var Chat = function() {
console.log("init");
function debug(txt) {
console.log(txt);
}
function keyPressedFunction(e){
console.log("keyPressed");
}
this.sendText = function() {
var texte = document.getElementById('shoutBoxInput').value;
if (texte=="") return;
document.getElementById('shoutBoxInput').value ="";
debug("sendTexte:"+texte);
}
this.receiveText = function(username, texte) {
}
document.getElementById('shoutBoxInput')
.addEventListener("keypress", keyPressedFunction, false);
}
If you do this, then you don't necessarily have to declare your functions before you use them, but it would be good style to do so nonetheless.

Create a function like jQuery(document).ready

How can I do that?
It seems that you can have multiple jQuery's ready() functions, and they will all run when the DOM is loaded.
So how can I create my own ready()-like function? :)
function _addEvent(e, evt, handler){
if(evt == "ready")
evt = "DOMContentLoaded";
if(typeof handler !== 'function')return;
if (e.addEventListener)
e.addEventListener(evt, handler, false);
else if (e.attachEvent)
e.attachEvent("on" + evt, handler);
else
{
var oldHandler = e["on" + evt];
function newHandler(event){
handler.call(e, event);
if(typeof oldhandler === 'function')oldhandler.call(e, event);
}
}
}
var _events = ["ready", "click", "mousedown"]; //...
var _myLib = function(item){
function eventWorker(item, event){
this.add = function(handler){
_addEvent(item, event, handler);
};
}
for(var i=0;i<_events.length;i++)
this[_events[i]] = (new eventWorker(item, _events[i])).add;
};
var MyLib = function(item){
return new _myLib(item);
};
MyLib(document).ready(function(){alert("I am ready!");});
Test =>
http://jsfiddle.net/vgraN/
First, you need to identify what it is you need the function for - is it to respond to a particular browser event?
jQuery's $(document).ready(fn) uses an array internally to hold the functions to execute when the DOM has loaded. Adding a new ready(fn) call appends the function fn to the array. When the DOM has loaded (which is detected in various ways according to which browser the code is executing within), each function in turn in the array is executed. Any functions added using ready(fn) after the DOM has loaded are executed immediately.
In summary, you can use an array to store the functions to execute whenever it is that you need to execute them.
Take a look at domready, a standalone port of the ready(fn) function from jQuery to get some ideas about how to go about it.
It sounds like you want to make an array of functions and append new callbacks to it.
It's not easy to do cross browser.
If you assume the DOMContentLoaded event exists then you can just make
var domready = (function () {
var cbs = [];
document.addEventListener("DOMContentLoaded", function () {
cbs.forEach(function (f) {
f();
});
});
return function (cb) {
cbs.push(cb);
};
})();
You can use other fallbacks like window.onload and a hackish scroll check like jQuery does.
I'd recommend either using domready or reading the source.
Do you want to create a function which when passed a function will call that function at a particular time? (Also, it can be called multiple times.) If so this is how I would do it it. (Based on jQuery code.)
var funcQueue = (function () {
var funcList = [];
function runAll() {
var len = funcList.length,
index = 0;
for (; index < len; index++)
funcList[index].call(); // you can pass in a "this" parameter here.
}
function add(inFunc) {
funcList.push(inFunc);
}
})();
To use:
funcQueue.add(function () { alert("one"); });
funcQueue.add(function () { alert("two"); });
funcQueue.runAll(); // should alert twice.

JavaScript window resize event

How can I hook into a browser window resize event?
There's a jQuery way of listening for resize events but I would prefer not to bring it into my project for just this one requirement.
Best practice is to add to the resize event, rather than replace it:
window.addEventListener('resize', function(event) {
...
}, true);
An alternative is to make a single handler for the DOM event (but can only have one), eg.
window.onresize = function(event) {
...
};
jQuery may do some work to ensure that the resize event gets fired consistently in all browsers, but I'm not sure if any of the browsers differ, but I'd encourage you to test in Firefox, Safari, and IE.
First off, I know the addEventListener method has been mentioned in the comments above, but I didn't see any code. Since it's the preferred approach, here it is:
window.addEventListener('resize', function(event){
// do stuff here
});
Here's a working sample.
Never override the window.onresize function.
Instead, create a function to add an Event Listener to the object or element.
This checks and incase the listeners don't work, then it overrides the object's function as a last resort. This is the preferred method used in libraries such as jQuery.
object: the element or window object
type: resize, scroll (event type)
callback: the function reference
var addEvent = function(object, type, callback) {
if (object == null || typeof(object) == 'undefined') return;
if (object.addEventListener) {
object.addEventListener(type, callback, false);
} else if (object.attachEvent) {
object.attachEvent("on" + type, callback);
} else {
object["on"+type] = callback;
}
};
Then use is like this:
addEvent(window, "resize", function_reference);
or with an anonymous function:
addEvent(window, "resize", function(event) {
console.log('resized');
});
Solution for 2018+:
You should use ResizeObserver. It is a browser-native solution that has a much better performance than to use the resize event. In addition, it not only supports the event on the document but also on arbitrary elements.
var ro = new ResizeObserver( entries => {
for (let entry of entries) {
const cr = entry.contentRect;
console.log('Element:', entry.target);
console.log(`Element size: ${cr.width}px x ${cr.height}px`);
console.log(`Element padding: ${cr.top}px ; ${cr.left}px`);
}
});
// Observe one or multiple elements
ro.observe(someElement);
Currently, Firefox, Chrome, Safari, and Edge support it. For other (and older) browsers you have to use a polyfill.
The resize event should never be used directly as it is fired continuously as we resize.
Use a debounce function to mitigate the excess calls.
window.addEventListener('resize',debounce(handler, delay, immediate),false);
Here's a common debounce floating around the net, though do look for more advanced ones as featuerd in lodash.
const debounce = (func, wait, immediate) => {
var timeout;
return () => {
const context = this, args = arguments;
const later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
const callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
This can be used like so...
window.addEventListener('resize', debounce(() => console.log('hello'),
200, false), false);
It will never fire more than once every 200ms.
For mobile orientation changes use:
window.addEventListener('orientationchange', () => console.log('hello'), false);
Here's a small library I put together to take care of this neatly.
I do believe that the correct answer has already been provided by #Alex V, yet the answer does require some modernization as it is over five years old now.
There are two main issues:
Never use object as a parameter name. It is a reservered word. With this being said, #Alex V's provided function will not work in strict mode.
The addEvent function provided by #Alex V does not return the event object if the addEventListener method is used. Another parameter should be added to the addEvent function to allow for this.
NOTE: The new parameter to addEvent has been made optional so that migrating to this new function version will not break any previous calls to this function. All legacy uses will be supported.
Here is the updated addEvent function with these changes:
/*
function: addEvent
#param: obj (Object)(Required)
- The object which you wish
to attach your event to.
#param: type (String)(Required)
- The type of event you
wish to establish.
#param: callback (Function)(Required)
- The method you wish
to be called by your
event listener.
#param: eventReturn (Boolean)(Optional)
- Whether you want the
event object returned
to your callback method.
*/
var addEvent = function(obj, type, callback, eventReturn)
{
if(obj == null || typeof obj === 'undefined')
return;
if(obj.addEventListener)
obj.addEventListener(type, callback, eventReturn ? true : false);
else if(obj.attachEvent)
obj.attachEvent("on" + type, callback);
else
obj["on" + type] = callback;
};
An example call to the new addEvent function:
var watch = function(evt)
{
/*
Older browser versions may return evt.srcElement
Newer browser versions should return evt.currentTarget
*/
var dimensions = {
height: (evt.srcElement || evt.currentTarget).innerHeight,
width: (evt.srcElement || evt.currentTarget).innerWidth
};
};
addEvent(window, 'resize', watch, true);
window.onresize = function() {
// your code
};
The following blog post may be useful to you: Fixing the window resize event in IE
It provides this code:
Sys.Application.add_load(function(sender, args) {
$addHandler(window, 'resize', window_resize);
});
var resizeTimeoutId;
function window_resize(e) {
window.clearTimeout(resizeTimeoutId);
resizeTimeoutId = window.setTimeout('doResizeCode();', 10);
}
The already mentioned solutions above will work if all you want to do is resize the window and window only. However, if you want to have the resize propagated to child elements, you will need to propagate the event yourself. Here's some example code to do it:
window.addEventListener("resize", function () {
var recResizeElement = function (root) {
Array.prototype.forEach.call(root.childNodes, function (el) {
var resizeEvent = document.createEvent("HTMLEvents");
resizeEvent.initEvent("resize", false, true);
var propagate = el.dispatchEvent(resizeEvent);
if (propagate)
recResizeElement(el);
});
};
recResizeElement(document.body);
});
Note that a child element can call
event.preventDefault();
on the event object that is passed in as the first Arg of the resize event. For example:
var child1 = document.getElementById("child1");
child1.addEventListener("resize", function (event) {
...
event.preventDefault();
});
You can use following approach which is ok for small projects
<body onresize="yourHandler(event)">
function yourHandler(e) {
console.log('Resized:', e.target.innerWidth)
}
<body onresize="yourHandler(event)">
Content... (resize browser to see)
</body>
<script language="javascript">
window.onresize = function() {
document.getElementById('ctl00_ContentPlaceHolder1_Accordion1').style.height = '100%';
}
</script>
var EM = new events_managment();
EM.addEvent(window, 'resize', function(win,doc, event_){
console.log('resized');
//EM.removeEvent(win,doc, event_);
});
function events_managment(){
this.events = {};
this.addEvent = function(node, event_, func){
if(node.addEventListener){
if(event_ in this.events){
node.addEventListener(event_, function(){
func(node, event_);
this.events[event_](win_doc, event_);
}, true);
}else{
node.addEventListener(event_, function(){
func(node, event_);
}, true);
}
this.events[event_] = func;
}else if(node.attachEvent){
var ie_event = 'on' + event_;
if(ie_event in this.events){
node.attachEvent(ie_event, function(){
func(node, ie_event);
this.events[ie_event]();
});
}else{
node.attachEvent(ie_event, function(){
func(node, ie_event);
});
}
this.events[ie_event] = func;
}
}
this.removeEvent = function(node, event_){
if(node.removeEventListener){
node.removeEventListener(event_, this.events[event_], true);
this.events[event_] = null;
delete this.events[event_];
}else if(node.detachEvent){
node.detachEvent(event_, this.events[event_]);
this.events[event_] = null;
delete this.events[event_];
}
}
}

Categories

Resources