Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

addEventListener to simple directive example in AngularJS

Trying to get this very basic directive example to work. From some investigation, 'elem' seems to be an object of HTMLHeadingElement (which inherits from Element). Not sure why elem.addEventListener would not work. Also, elem.bind seems to work however this isn't the global bind, right?

Also, would be great if someone could touch upon Document Object Model (DOM) Level 2 HTML Specification vs Document Object Model (DOM) Level 1 Specification. Happened to come across this for the first time, is this a new Object hierarchy for DOM elements?

Below is the link function of my directive:-

link: function(scope, elem, attrs) {
  // elem will be HTMLHeadingElement object!
  scope.name = 'New Micheal!';
  elem.addEventListener('click', function(e) {
      elem.css('background-color', 'red');
    })
    /*elem.bind('mouseover', function(e) {
      elem.css('background-color', 'red');
    });
    elem.bind('mouseout', function(e) {
      elem.css('background-color', 'white');
    });*/
}
like image 463
noi.m Avatar asked Jun 23 '16 03:06

noi.m


3 Answers

elem isn't a DOM element it is a jQlite object (angular.element) or a jQuery object if jQuery included in page before angular.js

The DOM node is elem[0]

Can use the angular.element API which is a subset of jQuery methods.

For click listener would be:

elem.bind('click',handlerfunc);

This isn't the global bind()

No...it's part of above API and matches jQuery bind()

bind() (deprecated, use on()) - Does not support namespaces, selectors or eventData

like image 74
charlietfl Avatar answered Nov 02 '22 00:11

charlietfl


elem is a jquery (or jqlite) wrapped element. It is not an instance of HTMLHeadingElement (although the underlying wrapped instance can be accessed).

To add the click handler, you should be using: elem.click(function(e) { ... }); instead of addEventListener.


EDIT

The above approach only works if you are using jquery proper (not jqlite). However, in general, you should not be adding handlers through JS. The angular way is to do this in the template.

Something like this:

scope.colorHandler = function() {
  elem.css('background-color', 'red');
});

And in the template:

template: '<div ng-click="name = \'colorHandler()\'"><h3>Hello {{name}}!!</h3></div>',

In this example, clicking on the div will call the color handler.

This is still not canonical angular, since you should be handling css changes through changes in css classes and ng-class, but this is getting closer and I hope it illustrates the point.

like image 34
Andrew Eisenberg Avatar answered Nov 02 '22 00:11

Andrew Eisenberg


You have 2 jQlite and javascript options:

javascript:

elem[0].addEventListener('click', function(e) {
   elem.css('background-color', 'red');
});

jQlite:

elem.bind('click', function(e) {
    elem.css('background-color', 'red');
});
like image 34
MeTe-30 Avatar answered Nov 01 '22 22:11

MeTe-30