在AngularJS中访问被点击的元素

16 浏览
0 Comments

在AngularJS中,我们可以使用以下语法来获取点击事件(以及其中的目标元素)(注意$event参数传递给setMaster函数):

function AdminController($scope) {    
  $scope.setMaster = function(obj, $event){
    console.log($event.target);
  }
}

然而,这种解决方法并不是非常符合AngularJS的方式。AngularJS的重点在于模型操作。我们可以改变模型,然后让AngularJS来处理渲染。

在AngularJS中解决这个问题的方式(不使用jQuery和不需要传递$event参数)是:

<div ng-controller="AdminController">
    <ul class="list-holder">
        <li ng-repeat="section in sections" ng-class="{active : isSelected(section)}">
            <a ng-click="setMaster(section)">{{section.name}}</a>
        </li>
    </ul>
    <hr>
    {{selected | json}}
</div>

控制器中的方法如下:

$scope.setMaster = function(section) {
    $scope.selected = section;
}
$scope.isSelected = function(section) {
    return $scope.selected === section;
}

完整的jsFiddle示例在这里:http://jsfiddle.net/pkozlowski_opensource/WXJ3p/15/

需要注意的是,$event只有在标记中传递时才起作用:ng-click="setMaster(section, $event)"

是否有关于这个问题的任何AngularJS文档的链接?

没有,它必须传递给函数。不过,实际上,在控制器中引用DOM特定的内容可能不是一个好主意。通常情况下,当使用$event时,它是用于停止传播或类似的上下文中:<a ng-click="doSomething(); $event.stopPropagation()">Click Just Me</a>

我在使用$event.target时遇到了问题,因为我的按钮内有一个图标。所以,有时候目标结果是按钮,有时候是图标(取决于我点击的位置)。我使用$event.currentTarget代替target,它完美地工作。

请注意,只有在需要进行低级DOM操作时才需要传递$event参数。如果按照AngularJS的方式解决问题,绝对不需要这个参数。

你可以在不从视图中传递$event的情况下访问函数中的DOM元素,查看下面的解决方案。

需要注意的是,访问$event.target的另一个用例是用于操作可访问性的焦点。不幸的是,当涉及到可访问性时,并没有"Angular方式",因为作者在这方面基本上没有关注。

谢谢!我之前不知道ng-directive函数可以获取参数$event。

虽然像这样使用$event.target可能不是"Angular方式",但我觉得在一个有很多项需要监听器来评估更改的大型ng-repeat列表中,并不高效。点击一个元素意味着整个列表中的每个项都必须重新评估,对吗?为什么不只是用$event.target来针对那个特定的项进行操作,例如切换CSS类。你觉得呢?我正在开发一个Phonegap应用,需要尽可能提高性能。

我还想推荐使用$event.currentTarget而不是$event.target。如果带有ng-click的元素有子元素,如果点击子元素,$event.target就会变成子元素。而$event.currentTarget将始终指向具有指定ng-click的元素。

是正确的。我不会否认$event.target不是Angular方式,但是这里展示的Angular方式非常低效。isSelected会在每个ng-repeat迭代的每个元素上被多次调用。在应用程序初始化之后,它是3*n,对于每次点击,它是2*n。所以在上面的示例中,只有3个元素,当它加载并且您点击一次时,isSelected总共被调用了18次。现在将其扩展到带有真实列表的真实生产应用程序。有时候Angular方式并不总是最好的方式。

0