Is attaching an onchange object a closure?

777 views Asked by At

I have searched prior SO posts here, here and here, and couldn't an answer that made sense to me. This should be a basic question, but I'm not understanding the posts I find. They don't seem to address using a this parameter.

I want to programatically add an input with an onchange event, such that the final result is this:

 <input type="button" onchange="handleButtonOnChange(this)">ClickMe</input>

I am working on a project that is using an embedded IE6 browser inside a old Delphi application, so I have to have a solution that is IE6 compatible (yes, IE6 is horrible, but there are reasons I am stuck with it for now).

My initial attempt was this:

var DaySelect = document.createElement("select");
DaySelect.id = ParentID+"-day";
DaySelect.disabled = true;
MonthSelect.onchange="handleDayChange(this);"  //<--- not correct
Parent.appendChild(DaySelect);

I then read that the .onchange should be assigned an object, not a string, and one should use this instead:

MonthSelect.onchange=handleDayChange;  //<--- '(this)' removed

But it seem to me that this will result in this element (notice the missing this parameter)

 <input type="button" onchange="handleButtonOnChange">ClickMe</input>

If I use the line below, instead, won't this make a closure, and the 'this' will refer to the event at the time the object is assigned to the .onchange property, instead of being the event at the time of the change event?

//Does the line below make a closure?  
MonthSelect.onchange=handleDayChange(this);  //<-- What does 'this' refer to?

I'm a relatively new web programmer, but long time Delphi programmer. Closures still make my head hurt. I appreciate any help in this.

Also, I read here about using addEventListener and the problems with older versions of IE, and the last post on the page provides a work around. But I don't understand how it works.

EDIT -- And what about passing other parameters? It seems that many event handlers will need to have parameters specific for the attached element. It seems that it is just not possible to add a listener with any parameters.

1

There are 1 answers

2
Trey On BEST ANSWER

A simple closure if you are creating the elements in JS as you show:

var DaySelect = document.createElement("select");
DaySelect.id = ParentID+"-day";
DaySelect.disabled = true;
MonthSelect.onchange=function(){handleDayChange(DaySelect);};
Parent.appendChild(DaySelect);

Since the function is created inside the scope that you create the element in, the same variables will be available to it.

EDIT:

Additional parameters can be passed with this method, for example, the anonymous function we create and attach as the handler will still have the event object sent to it:

function(e){handleDayChange(DaySelect, e);};

In the event object you will have access to the event target, but in your example the event target and "this" are not the same element, so there would be no way for the handler to know about the DaySelect element.

jQuery makes a lot of event handling much simpler which is one of the reasons many people use it, it also normalizes it's methods between various browsers so you don't have to write multiple versions of the same code (in most cases)