How could I properly access the closest element, as the below jQuery code acplishes, in Angular without using jQuery?
link: function (scope, element, attrs) {
function handler($event) {
if(!($event.target).closest(element).length) {
scope.$apply(function () {
$parse(attrs.clickOutside)(scope);
});
}
}
}
How could I properly access the closest element, as the below jQuery code acplishes, in Angular without using jQuery?
link: function (scope, element, attrs) {
function handler($event) {
if(!($event.target).closest(element).length) {
scope.$apply(function () {
$parse(attrs.clickOutside)(scope);
});
}
}
}
Share
Improve this question
asked Oct 2, 2015 at 17:30
MattDionisMattDionis
3,61610 gold badges55 silver badges110 bronze badges
4
-
What that code is really doing is checking if
$event.target
is a child ofelement
. So you can useparent
to keep going up the tree and check if any of them areelement
– JoseM Commented Oct 2, 2015 at 17:33 -
Show the relevant html and where
handler
is being used. Being inside a directive one might assume that event is bound to element or a descendant and therefore condition would always be true – charlietfl Commented Oct 2, 2015 at 17:57 -
1
what are you actually trying to acplish here? This es off as an XY question, because you ask how to do something from one framework in context of another framework, but don't actually explain why you need the function. There is probably a way to acplish your task without having to resort to this kind of manipulation. And just so you are aware, using
element
is using JQuery if it is available, or JQLite otherwise. you aren't escaping the JQuery way of thinking here. – Claies Commented Oct 2, 2015 at 20:40 -
I'm trying to test whether
$event.target
is insideelement
. More specifically, did the user click something inside the element in question or outside. I had working code using jQuery, but I'm trying to avoid using jQuery in my Angular app and instead rely on the jQlite subset which Angular es with. – MattDionis Commented Oct 2, 2015 at 20:49
2 Answers
Reset to default 6I ended up simply checking if the element contains $event.target
. The key here is that you must access element[0]
and not simply element
:
link: function(scope, element, attrs) {
function handler($event) {
if (!element[0].contains($event.target)) {
scope.$apply(function() {
$parse(attrs.clickOutside)(scope);
});
}
}
}
Something like this can be used to extend the angular.element functionality:
angular.element.prototype.closest = function closest( selector )
{
if( selector && selector.length )
{
var startChar = selector.substring( 0, 1 );
switch( startChar )
{
case '.':
return this.hasClass( selector.substring( 1, selector.length ) ) ? this : ( this.parent().length ? this.parent().closest( selector ) : this.parent() );
break;
case '#':
return selector.substring( 1, selector.length ) == this[0].id ? this : ( this.parent().length ? this.parent().closest( selector ) : this.parent() );
break;
default: //tagname
return ( this[0].tagName && selector.toLowerCase() == this[0].tagName.toLowerCase() ) ? this : ( this.parent().length ? this.parent().closest( selector ) : this.parent() );
break;
}
}
else
{
return this.parent();
}
}