Dyrektywa, która uruchamia zdarzenie po kliknięciu poza elementem

Wiem, że wiele pytań należy zadać w podobny sposób. Ale nikt naprawdę nie rozwiązuje mojego problemu.

Próbuję zbudować dyrektywę, która wykona wyrażenie, gdy kliknie myszką poza bieżącym elementem.

Dlaczego potrzebuję tej funkcji? Buduję aplikację, w tej aplikacji są 3 rozwijane menu, 5 rozwijanych list (jak wybrane). Wszystko to są wytyczne kątowe. Załóżmy, że wszystkie te dyrektywy są różne. Mamy więc 8 dyrektyw. A wszystkie z nich wymagają tej samej funkcji: po kliknięciu poza element, należy ukryć listę rozwijaną.

Mam na to 2 rozwiązania, ale oba mają problem:

Rozwiązanie A:

app.directive('clickAnywhereButHere', function($document){
  return {
    restrict: 'A',
    link: function(scope, elem, attr, ctrl) {
      elem.bind('click', function(e) {
        // this part keeps it from firing the click on the document.
        e.stopPropagation();
      });
      $document.bind('click', function() {
        // magic here.
        scope.$apply(attr.clickAnywhereButHere);
      })
    }
  }
})

Oto przykład rozwiązania A:Kliknij tutaj

Po kliknięciu pierwszego menu rozwijanego, a następnie pracy, a następnie kliknięciu drugiego wejścia, pierwsze powinno się ukryć, ale nie.

Rozwiązanie B:

app.directive('clickAnywhereButHere', ['$document', function ($document) {
    directiveDefinitionObject = {
        link: {
            pre: function (scope, element, attrs, controller) { },
            post: function (scope, element, attrs, controller) {
                onClick = function (event) {
                    var isChild = element.has(event.target).length > 0;
                    var isSelf = element[0] == event.target;
                    var isInside = isChild || isSelf;
                    if (!isInside) {
                        scope.$apply(attrs.clickAnywhereButHere)
                    }
                }
                $document.click(onClick)
            }
        }
    }
    return directiveDefinitionObject
}]);

Oto przykład rozwiązania B:Kliknij tutaj

Rozwiązanie Działa, jeśli na stronie jest tylko jedna dyrektywa, ale nie w mojej aplikacji. Ponieważ zapobiega to bulgotaniu, więc najpierw, gdy kliknę dropdown1, pokaż dropdown1, a następnie kliknę dropdown2, kliknij event, aby zapobiec, więc dropdown1 nadal będzie tam wyświetlany, nawet jeśli kliknę poza dropdown1.

Rozwiązanie B działające w mojej aplikacji, z której teraz korzystam. Ale problem polega na tym, że powoduje problem z wydajnością. Za dużo kliknięć można obsługiwać przy każdym kliknięciu w dowolnym miejscu w aplikacji. W moim obecnym przypadku istnieje wiązanie zdarzeń z 8 kliknięciami z dokumentem, więc każde kliknięcie wykonuje 8 funkcji. Które powodują, że moja aplikacja jest bardzo wolna, szczególnie w IE8.

Czy jest na to jakieś lepsze rozwiązanie? Dzięki

questionAnswers(8)

yourAnswerToTheQuestion