Wie gehe ich mit Rechtsklick-Ereignissen in angle.js um?


69

Gibt es eine Möglichkeit, ein Element so einzurichten, dass es beim Linksklick (ng-click) eine Aktion und beim Rechtsklick eine weitere Aktion ausführt?

Im Moment habe ich so etwas wie:

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

Und ich möchte auch in der Lage sein, mit der rechten Maustaste auf die Spanne zu klicken, um die Funktion decrement () auszuführen.

Antworten:


138

Sie können eine Direktive verwenden, um bestimmte Aktionen beim Klicken mit der rechten Maustaste mithilfe des contextmenuEreignisses zu binden :

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});
            });
        });
    };
});

Codebeispiel auf Geige


Das funktioniert gut, aber wenn ich versuche, ein neues Fenster über den Handler zu öffnen, wird es blockiert, wenn es durch Rechtsklick ausgelöst wird und nicht, wenn es durch Linksklick ausgelöst wird. Ich bin auf Chrom. jsfiddle.net/aslakhellesoy/QLHUV/3
Aslak Hellesøy

@ AslakHellesøy Wahrscheinlich, weil der Browser die ng-Rechtsklick-Direktive nicht als vom Benutzer initiiertes Ereignis erkennt.
Magne

@ AslakHellesøy Arbeitet für mich in Chrome (Version 34.0.1847.116 m)
Martin

1
@ Jer, Sie können mit $ event auf das Ereignis zugreifen. Sehen Sie sich dieses Beispiel an: jsfiddle.net/b0sx1ae1
Bastien Caudan

2
Tolle Antwort, obwohl ich es lieber nenne ngContextmenu(auch ändern attrs.ngContextmenuund wie verwenden ng-contextmenu="..."), weil es das Kontextmenü behandelt und keinen Rechtsklick, der von und behandelt werden ng-mousedownsoll . ng-mouseupng-click
MicroVirus

27

Hallo, das ist eine alte Frage, aber ich habe eine Lösung, die meiner Meinung nach in einigen Fällen einfacher sein kann. Die Anweisungen ngMousedown (und ngMouseup) werden mit der rechten Maustaste ausgelöst und haben Zugriff auf das ursprüngliche Mausereignis, $eventsodass Sie dies folgendermaßen tun können:

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

In der Steuerung können Sie dann Folgendes tun:

$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;
    }
}

Hier ist eine funktionierende Geige . Es funktioniert genauso wie die akzeptierte Antwort, erfordert jedoch nicht die Erstellung einer völlig neuen Richtlinie. Obwohl eine Direktive eine bessere Lösung sein kann, insbesondere wenn Sie vorhaben, vielen Dingen Rechtsklickfunktionen zuzuweisen. Aber trotzdem eine andere Option.


Ziemlich cool, danke. Für alle, die Probleme damit haben, muss sich das Attribut oncontextmenu genau auf dem Element befinden, auf das mit der rechten Maustaste geklickt wird. Hatte es auf dem Container und das Kontextmenü öffnete sich immer wieder. (Chrome 51.0.2700.0 dev-m)
Daniel Z.

1
@ Termi2610 funktioniert bei mir mit dem oncontextmenu auf dem Container. Chrom-Version: 54.0.2840.71
yannick1976

@ yannick1976 Habe es gerade mit meiner aktuellen Version (53.0.2785.143 m) mit demselben Container getestet, den ich im April verwendet habe. Und ja, es funktioniert. Es scheint ein Fehler in der Version zu sein, die ich zuvor verwendet habe.
Daniel Z.

7

Eine Möglichkeit ist die Verwendung einer Direktive, die einen Ereignishandler an ein Ereignis bindet contextmenu. Es fiel mir schwer, das Sprudeln zu stoppen, um zu verhindern, dass das Standardmenü angezeigt wird. Daher wurde der native Skript-Handler für hinzugefügt document. Versucht , mit e.stopPropagation(), e.preventDefault(), return falseetc. Das Überprüfen des Ziels im Dokumenthandler scheint gut zu funktionieren

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

Sie können diese Anweisung verwenden .

<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>
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.