Here's my version that detects and handles isolate scopes correctly and stops as soon as it finds the element. Angular's .scope()
and .isolateScope()
functions use the jquery .data()
object and if a scope is not found, they search up through the parent nodes of the element. We're already searching through all nodes, so it's a lot more efficient to skip the parent search and inspect .data()
directly.
const findScopeElement = $scope => {
const {$id, $root} = $scope;
let result;
const isolate = $scope !== $root &&
Object.getPrototypeOf($scope) === Object.getPrototypeOf($root);
const cls = isolate ? '.ng-isolate-scope' : '.ng-scope';
const search = (i, e) => {
const data = $(e).data();
const scope = isolate ? data.$isolateScope : data.$scope;
if(scope && scope.$id === $id) {
result = e;
return false;
}
};
$(cls).each(search);
if(!result) {
// could be an attribute directive
$(`:not(${cls})`).each(search);
}
return result;
}