2013-03-31 3 views
61

Есть ли способ создать элемент, чтобы он выполнял одно действие по щелчку левой кнопкой мыши (ng-click), а затем еще одно действие правой кнопкой мыши?Как обрабатывать события щелчка правой кнопкой мыши в angular.js?

Сейчас у меня есть что-то вроде:

<span ng-click="increment()">{{getPointsSpent()}}</span> 

И я хотел бы также иметь возможность щелкнуть правой кнопкой мыши на пролете, чтобы выполнить функцию декремент();

ответ

125

Вы можете использовать директиву, чтобы связать конкретные действия на правой кнопкой мыши, используя contextmenu событие:

app.directive('ngRightClick', function($parse) { 
    return function(scope, element, attrs) { 
     var fn = $parse(attrs.ngRightClick); 
     element.bind('contextmenu', function(event) { 
      scope.$apply(function() { 
       event.preventDefault(); 
       fn(scope, {$event:event}); 
      }); 
     }); 
    }; 
}); 

Code example on fiddle

+0

Это отлично работает, но если я попытаюсь открыть новое окно из обработчика, он блокируется при срабатывании по правому клику, а не при нажатии левой кнопкой мыши. Я на хроме. http://jsfiddle.net/aslakhellesoy/QLHUV/3/ –

+0

@ AslakHellesøy Возможно, потому, что браузер не распознает директиву ng-right-click в качестве инициированного пользователем события. – Magne

+0

@ AslakHellesøy Работает для меня в Chrome (версия 34.0.1847.116 м) – Martin

7

Один из способов - использовать директиву, которая связывает обработчик события с событием contextmenu. Мне было трудно остановить пузырьки, чтобы предотвратить появление меню по умолчанию, поэтому добавлен собственный обработчик сценариев для document. Пробовал с e.stopPropagation(), e.preventDefault(), return false и т.д. Проверка целевого в податчик, кажется, работает хорошо

app.directive('rightClick',function(){ 
    document.oncontextmenu = function (e) { 
     if(e.target.hasAttribute('right-click')) { 
      return false; 
     } 
    }; 
    return function(scope,el,attrs){ 
     el.bind('contextmenu',function(e){ 
      alert(attrs.alert);    
     }) ; 
    } 
}); 
<button right-click alert="You right clciked me">Right click me</button> 

DEMO http://plnkr.co/edit/k0TF49GVdlhMuioSHW7i

1

Вы может использовать это directive.

<div ng-controller="demoCtrl" save-content="classic-html"> 
    <div contextmenu="{{lists}}" class="box" click-menu="clickMenu(item)" right-click="rightClick($event)"> 
    <span>normal dropmenu</span> 
    </div> 
</div> 

<script type="text/javascript"> 
angular.module('demo', ['ngContextMenu']) 

    .controller('demoCtrl', ['$scope', function($scope) { 
    $scope.lists = [{ 
     name: '11' 
    }, { 
     name: '22' 
    }] 

    $scope.clickMenu = function (item) { 
     console.log(item); 
    }; 

    $scope.rightClick = function (event) { 
     console.log(event); 
    }; 
    }]) 
</script> 
20

Привет, это старый вопрос, но у меня есть решение, которое, я думаю, может быть проще в некоторых случаях. Директивы ngMousedown (и ngMouseup) вызываются правой кнопкой мыши и иметь доступ к исходному событию мыши через $event так что вы могли бы сделать это следующим образом:

<span ng-mousedown="handleClick($event)" 
     oncontextmenu="return false"> <!-- use this to prevent context menu --> 
      {{getPointsSpent()}} 
</span> 

Затем в контроллере, вы можете сделать следующее:

$scope.handleClick(evt) { 
    switch(evt.which) { 
     case 1: 
      increment(); // this is left click 
      break; 
     case 2: 
      // in case you need some middle click things 
      break; 
     case 3: 
      decrement(); // this is right click 
      break; 
     default: 
      alert("you have a strange mouse!"); 
      break; 
    } 
} 

Вот working fiddle. Он работает так же, как и принятый ответ, но не требует создания совершенно новой директивы. Хотя директива может быть лучшим решением, особенно если вы планируете прикрепить функции правого щелчка к множеству вещей. Но в любом случае, другой вариант.

+0

Довольно круто, спасибо. Для тех, у кого есть проблемы с этим, атрибут oncontextmenu должен быть точно на элементе с правосторонним щелчком. Если бы это было на контейнере, и контекстное меню продолжало открываться. (Chrome 51.0.2700.0 dev-m) –

+1

@ Termi2610 работает для меня с oncontextmenu на контейнере. chrome version: 54.0.2840.71 – yannick1976

+0

@ yannick1976 Просто протестировал его с моей текущей версией (53.0.2785.143 м) с тем же контейнером, который я использовал в апреле. И да, это работает. Похоже, что это была ошибка в версии, которую я использовал раньше. –

Смежные вопросы