title: Directive that fires an event when clicking outside of the element
body: <p>I know there are many questions ask similar thing. But no one really solve my issue.</p>
  
  <p>I'm trying to build an directive which will execute an expression when mouse click outside the current element.</p>
  
  <p>Why I need this function? I'm building an app, in this app, there are 3 dropdown menu, 5 dropdown list(like chosen). All these are angular directives. Let's assume all these directives are different. So we have 8 directives. And all of them need a same function: when click out side the element, need hide the dropdown.</p>
  
  <p>I have 2 solutions for this, but both got issue:</p>
  
  <p>Solution A:</p>
  
  <pre><code>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);
        })
      }
    }
  })
  </code></pre>
  
  <p>Here is an example for solution A: <a href="http://jsfiddle.net/4sjvc/2/">click here</a> </p>
  
  <p>When you click the first dropdown, then working, then click second input, the first should hide but not.</p>
  
  <p>Solution B:</p>
  
  <pre><code>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 &gt; 0;
                      var isSelf = element[0] == event.target;
                      var isInside = isChild || isSelf;
                      if (!isInside) {
                          scope.$apply(attrs.clickAnywhereButHere)
                      }
                  }
                  $document.click(onClick)
              }
          }
      }
      return directiveDefinitionObject
  }]);
  </code></pre>
  
  <p>Here is example for solution B: <a href="http://jsfiddle.net/4sjvc/3/">click here</a></p>
  
  <p>Solution A working if there is just one directive in the page but not in my app. Because it's prevent bubbling, so first when I click on dropdown1, show dropdown1, then click on dropdown2, click event be prevent, so dropdown1 still showing there even I click outside the dropdown1.</p>
  
  <p>Solution B working in my app which I'm using now. But the issue is it's cause a performance issue. Too many click event be handled on every single click on anywhere in the app. In my current case, there are 8 click event bind with document, so every click execute 8 functions. Which cause my app very slow, especially in IE8.</p>
  
  <p>So is there any better solution for this? Thanks</p>