3

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.

Community
  • 1
  • 1
kdtop
  • 541
  • 1
  • 7
  • 22
  • 1
    Should "this" point to the input element in your example? – Trey Jan 13 '16 at 22:52
  • I want to be able to have multiple elements use the same javascript handler. So my thought was that the handler would need to be passed the element that created the event. So yes, the 'this' would be the element that initiated the call. – kdtop Jan 13 '16 at 22:54
  • 1
    In your last code/comment question, `this` refers to the global `window` object (if called from global js context). Also in that code line, you're assigning the property the return value of the function, not the function itself. You are calling the function there. – Seth Battin Jan 13 '16 at 22:56
  • 1
    `MonthSelect.onchange="handleDayChange(this);"` or `DaySelect.onchange="handleDayChange(this);"` ? – Ruan Mendes Jan 13 '16 at 22:58
  • @JuanMendes You are correct. That was a bug that was confusing me. I caught it just before I read your post. I should have checked back sooner. Thanks! – kdtop Jan 13 '16 at 23:17

1 Answers1

1

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)

Trey
  • 5,480
  • 4
  • 23
  • 30
  • I'll try this and post back. As an aside, is the 'this' object available to the called handler if I don't explicitly pass it? I.e. is it somehow globally-scoped? – kdtop Jan 13 '16 at 23:00
  • 1
    The caller (the browser) sets `this` to the element that the event was registered on when calling your handler. Kind of like: 'myDiv.handler.call(myDiv, event)' – Ruan Mendes Jan 13 '16 at 23:17