object method as an event handler

zc2
zc2 used Ask the Experts™
on
There is an existing HTML code, which basically could be simplified to the following example.
HTML element's event handlers are methods of objects. One such object is created for every such html element.
Then the reference to the object is inserted as a custom attribute to the element ( obj ).

As I understand, that approach is very bad, because it creates loops in object references.
Could somebody suggest a better way to bind elements and the handler objects?

That element-object pairs should remain, I just need a more correct way to keep reference to the object to be used when an event fires.

Also, if it's possible, please do not suggest to use jQuery or any other library, I need a pure JavaScript/html solution.

<html>
<head>
<script>
function eventHandler( elem ) {
  this.elem = elem;
  this.click = function( ev ) {
    alert( "elem:" + elem.id );
  }
}

</script>
</head>
<body>

<a id="a" onclick="this.obj.click();" href="#">elem A</a>
<script>
(function() {
  var elm = document.getElementById("a");
  elm.obj = new eventHandler( elm );
})();
</script>

<a id="b" onclick="this.obj.click();" href="#">elem B</a>
<script>
(function() {
  var elm = document.getElementById("b");
  elm.obj = new eventHandler( elm );
})();
</script>

</body>
</html>

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Distinguished Expert 2017

Commented:
Check this...I create HTML elements with an onclick atrr.
Then I create a function passing an argument (arg)
In anchor element inside the onclick attr I pass the function with the "this" arg and return false to prevent bubbling.
<!DOCTYPE html>
<html>
    <head>
        <title>TODO supply a title</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
    <body>
        
<a onclick="showText(this);return false;" href="#">elem A</a>
<a onclick="showText(this);return false;" href="#">elem B</a>
<a onclick="showText(this);return false;" href="#">elem C</a>
<a onclick="showText(this);return false;" href="#">elem D</a>

<script>
function showText(arg){
    var text=arg.innerHTML;
    alert(text);
}
</script>
    </body>
</html>

Open in new window

Author

Commented:
I'm sorry if I did not explained that clear enough. It is an existing site which need to fix issues with Chrome browser. The objects I mentioned already implemented and I'm not going to redisign them.

I'm going to try store the reference in a collection, like the lines 19 and 27 would be
coll[elm.id] = new eventHandler( elm );

Open in new window

and the line 15 would be
<a id="a" onclick="coll[this.id].click();" href="#">elem A</a>

Can anyone suggest a better solution?
Most Valuable Expert 2017
Distinguished Expert 2018
Commented:
Something like this
var els = document.querySelectorAll('a');
for(var i = 0; i < els.length; i++) {
   els[i].obj = new eventHandler( els[i] );
}

Open in new window

This is not the way I would do it though - I don't see the value in creating a new object for every element when you can just assign a function that does what you need.
Should you be charging more for IT Services?

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!

Author

Commented:
Thank you for you answer. I agree that having a separate script section for each element is less effective than a single iterator which does the same at once. But my question was not about that. My concern is that the reference to javascript object is  assigned to an attribute of html element. Is that an allowed practice?   I am asking, because in Chrome v57 (v58 seemingly does not expose such behaviour), when the event fires, the obj attribute sometimes is found as undefined. I can't say why this happens and what could trigger that, but after I applied the changes I described earlier, that misbehavior did not happen even once.
Most Valuable Expert 2017
Distinguished Expert 2018

Commented:
Is that an allowed practice?
If it works it is allowed - is it a best practice - mostly depends on circumstances but that is what I was alluding to in my post when I said I would not do it this way. It is inefficient and not standard - so unless there is a specific reason for doing it that way I would not.

For me the rule of thumb is - is it more elaborate (complex) than it needs to be - is the extra complexity necessary for a particular purpose that cannot be solved any other way (in which case review your design). In most cases the answer would be don't do it this way.

Author

Commented:
The specific reason is that the handler objects and methods were already implemented in an existed site and we don't want to redesign that, at least now.
Say, the following is given: an existed site, somehow a complex object hierarchy which would require quite a time to redesign, methods of those objects to be called on elem events. Say, you have the above and have an assignment to fix the disappearing object reference issue in Chrome. What would you do?
Most Valuable Expert 2017
Distinguished Expert 2018

Commented:
If it ain't broke don't fix it. Get it working with what you have.

Author

Commented:
thank you

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start Today