AngularJS指令 - 如何让一个事件只触发一次,否则它会在多个元素被触发? [英] AngularJS Directive - How to let an event only be triggered once if otherwise it'll be triggered on multiple elements?

查看:138
本文介绍了AngularJS指令 - 如何让一个事件只触发一次,否则它会在多个元素被触发?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我目前有:

http://plnkr.co/edit/L9XqEyOtRSGHc9rqFPJX

我试图让这个当我preSS首次向下键时,焦点将移动到#DIV2 ;重复动作应该具有焦点移动到利丰GT; DIV:第一胎

I am trying to make it so that when I press the down key for the first time, the focus will move onto #div2; repeating the action should have the focus moving onto li > div:first-child.

在演示然而,在第一次向下键pressed,重点将跳转到利丰GT; DIV:第一胎直接,因为无论是键地图#DIV1 #DIV2 捕获时的相同keydown事件,所以重点从#DIV1 跳转到#DIV2 然后#DIV2 利丰GT; DIV:第一胎一气呵成

In the demo however, upon the first time the down key is pressed, the focus will jump to li > div:first-child directly, because both the key-map on #div1 and #div2 captured the same keydown event, so the focus jumps from #div1 to #div2 then #div2 to li > div:first-child in one go.

我应该如何解决这个问题,或者更好的,反正是有提高的是如何codeS的结构?我不知道这些事件侦听器是否连接到DOM中的最佳方式现在。

How should I solve this issue or, better yet, is there anyway to improve how the codes are structured? I am not sure whether those event listeners are attaching to the DOM in the optimal fashion right now.

推荐答案

您的附加的keydown 处理程序为每个元素的文档。我不认为 stopPropagation()将没有任何好处,因为这两个处理程序是相同的元素,它不会从文件传播起来,但双方仍会触发。

You are attaching a keydown handler to the document for each element. I don't think stopPropagation() will do any good because the two handlers are on the same element and it won't propagate up from document but both will still fire.

我建议重新评估你如何接近它。你只希望元素为重点类有它的选择进行评估,那么为什么不换与你的指令元素所有这些因素,并请有听只有一次,选择元素来采取行动。

I suggest re-evaluating how you're approaching it. You only wish the element with the focus class to have it's options evaluated, so why not wrap all those elements in an element with your directive and have it listen only once and choose the element to act on.

(plunker)

  <div key-mapped="">
    <!-- children will apply key map of element with focus class -->
    <div id="div1" class="focus" key-map="{
      40: '#div2'
    }">Hello</div>

指令:

  }).directive('keyMapped', function($rootScope) {
    return {
      restrict: 'A',
      link: function(scope, element, attr) {
        angular.element(document).bind('keydown', function(event) {
          var target = $(element).find('.focus');
          console.log('target: ' + target);

          var options = scope.$eval(target.attr('key-map'));

---- ----编辑

----EDIT----

有人让我知道,如果它不是一个很好的做法,但你总是把你的指令,对象上的事件处理程序,并确保它只能设置一次,并发送自定义事件的元素与你绑定'专注'类在你的链接功能。

Someone let me know if it's not a good practice, but you could always put the event handler on your directive object and ensure it is only set once and send a custom event to the element with the 'focus' class that you bind to in your link function.

(plunker)

}).directive('keyMap', function($rootScope) {
  var dir = {
    onKeydown: function(event) {
      var element = document.querySelector('.focus');
      var newEvent = new CustomEvent("keyMapKeydown", {
        detail: { keyCode: event.keyCode },
        bubbles: false,
        cancelable: true
      });
      element.dispatchEvent(newEvent);
    },
    registered: false, // ensure we only listen to keydown once
    restrict: 'A',
    link: function(scope, element, attr) {
      // register listener only if not already registered
      if (!dir.registered) {
        dir.registered = true;
        angular.element(document).bind('keydown', dir.onKeydown);
      }

      var options = scope.$eval(attr.keyMap);

      // listen for custom event which will be dispatched only to the
      // element that has the 'focus' class
      element.bind('keyMapKeydown', function(event) {
        var keyCode = event.detail.keyCode;
        if (options && (keyCode in options)) {
          element.removeClass('focus');
          angular.element(document.querySelector(options[keyCode])).addClass('focus');                
          event.stopPropagation();
        }
      });
    }
  };

这篇关于AngularJS指令 - 如何让一个事件只触发一次,否则它会在多个元素被触发?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆