title: Javascript how to dismiss context menu if user clicks elsewhere
body: <p>I have html images with hot spots (HTML Area elements).  And I have code which can show a context menu when a hot spot is right clicked because in some cases the hot spot can logically navigate to one than more destination.</p>
  
  <p>I have some nice working code based on the W3C planets example.  My menu appears close to the hot spot and the styles work nice.   And if I click on an item it will navigate through.</p>
  
  <p>The menu is dynamic and will in fact be piopulated by Angular code and JSON.  For the time being the menu is hardcoded with a mock function.</p>
  
  <p>If an item is clicked the menu dismisses (and the navigation follows).  I know my hide menu code works because I have a hide menu button for testing.</p>
  
  <p><em>My problem is once the menu is showing I cannot figure out how to let the user dismiss the menu  $('body').click(hideMenu) [line 130] does not work in that it is not accepting the function as a pointer (sorry if wrong term) for executing later; instead it executes it immediately, even though I have omitted the brackets.</em></p>
  
  <p>The code is available here at JSFiddle <a href="http://jsfiddle.net/simonmeaden/98mukrff/8/" rel="nofollow">http://jsfiddle.net/simonmeaden/98mukrff/8/</a> although it is not working in the fiddle.  What does work works launched from Visual Studio.</p>
  
  <pre><code>&lt;!DOCTYPE html&gt;
  &lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
  &lt;head&gt;
      &lt;link href="contextMenus.css" rel="stylesheet" /&gt;
      &lt;title&gt;&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
      &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js" charset="utf-8"&gt;&lt;/script&gt;
      &lt;script src="//code.jquery.com/jquery-1.11.3.min.js"&gt;&lt;/script&gt;
      &lt;script src="JavaScript1.js"&gt;&lt;/script&gt;
  
      &lt;table&gt;
          &lt;tr&gt;
              &lt;td&gt;Some text to shift image along&lt;/td&gt;
              &lt;td&gt;
                  &lt;img id="planets" src="http://www.w3schools.com/tags/planets.gif" usemap="#planetmap"&gt;
                  &lt;map name="planetmap" width="145" height="126" alt="Planets"&gt;
                      &lt;area id="planetmap_AreaSun" shape="rect" coords="0,0,82,126" href="http://www.w3schools.com/tags/sun.htm" alt="Sun"&gt;
                      &lt;area id="planetmap_AreaMercury" shape="circle" coords="90,58,3" href="http://www.w3schools.com/tags/mercur.htm" alt="Mercury"&gt;
                      &lt;area id="planetmap_AreaVenus" shape="circle" coords="124,58,8" href="http://www.w3schools.com/tags/venus.htm" alt="Venus"&gt;
                  &lt;/map&gt;
              &lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;
                  &lt;ul class="context-menu" id="my_custom_menu"&gt;
                      &lt;!--style="display:none;"--&gt;
                      &lt;li&gt;Strawberry&lt;/li&gt;
                      &lt;li&gt;Raspberry&lt;/li&gt;
                  &lt;/ul&gt;
              &lt;/td&gt;
          &lt;/tr&gt;
      &lt;/table&gt;
          &lt;!--&lt;button id="button_ShowMenu2" onclick="setMenu('my_custom_menu', this, dynamicMenu())" type="button"&gt;Show Menu&lt;/button&gt; --&gt;
          &lt;button id="button_ShowMenu" type="button"&gt;Show Menu&lt;/button&gt;
          &lt;button id="button_HideMenu" onclick="hideMenu()" type="button"&gt;Hide Menu&lt;/button&gt;
  
  &lt;/body&gt;
  
  &lt;/html&gt;
  </code></pre>
  
  <p>the styles</p>
  
  <pre><code>.context-menu {
      /*position: absolute;*/
      display: block;
      background-color: #f2f2f2;
      border-radius: 4px;
      font-family: Arial, sans-serif;
      font-size: 14px;
      min-width: 150px;
      border: 1px solid #d4d4d4;
      z-index:1200;
      list-style-type: none;
      text-decoration: none;
  }
  .context-menu ul {
      list-style-type: none;
      margin: 4px 0px;
      padding: 0px;
      cursor: default;
  }
  .context-menu ul li {
      padding: 4px 16px;
  }
  .context-menu ul li:hover {
      background-color: #4677f8;
      color: #fefefe;
  }
  
  
  a {
      text-decoration: none;
  }
  
  .context-menu ul li a {
      text-decoration: none;
  }
  
  .context-menu ul li:hover a {
      text-decoration: none;
  }
  
  .context-menu ul li a:hover, a:hover span {
      background-color: #4677f8;
      color: #fefefe;
  }
  </code></pre>
  
  <p>the javascript</p>
  
  <pre><code>function hideMenu() {
      console.log("hideMenu entered");
      var sMenuId = $('body').data('data-activeMenu');
      if (sMenuId !== '') {
          var jqMenu = $('#' + sMenuId);
  
          if (jqMenu) {
              jqMenu.css('display', 'none');
          } else {
              alert("menu (ul) id '" + sMenuId + "' not found!");
          }
      } else {
          alert("menu id '" + sMenuId + "' is null!");
      }
  }
  
  $(document).ready(function () {
  
      wireUpContextMenu('#planetmap_AreaVenus');
      wireUpButton();
      var gMousepos = [0, 0];
      document.onmousemove = function (evt) {
          evt = evt || window.event;
          if (typeof evt.pageX != 'undefined') {
              // Firefox support
              gMousepos = [evt.pageX, evt.pageY];
          } else {
              // IE support
              var scrollpos = getDocScrollPos();
              gMousepos = [evt.clientX + scrollpos[0], evt.clientY + scrollpos[1]];
          };
      };
  
  
      //alert("run");
  
      function dynamicMenu() {
          var fruits = [{
              itemText: "Apple",
              href: "http:\/\/images.clipartpanda.com\/teacher-apple-clipart-apple-clipartclipart---simple-red-apple-3e7q8rci.png"
          }, {
              itemText: "Orange",
              href: "http:\/\/www.google.com"
          }, {
              itemText: "Banana",
              href: "http:\/\/www.bbc.co.uk"
          }, {
              itemText: "Grape",
              href: "http:\/\/www.hotmail.com"
          }];
          return fruits;
      }
  
  
      function wireUpContextMenu(elementId) {
          var elementForMenuLaunch = $(elementId);
          if (elementForMenuLaunch) {
              elementForMenuLaunch.bind('contextmenu', function (e) {
                  e.preventDefault();
                  var jqElement = $(this);
                  //var mousepos=getMousePos();
                  var position = jqElement.position();
                  var lPixelLeft =  gMousepos[0];//position.left;
                  var lPixelTop = gMousepos[1];//position.top;
                  setMenuInner('my_custom_menu', lPixelLeft, lPixelTop, dynamicMenu());
  
                  //alert('The eventhandler will make sure, that the contextmenu doesn\'t appear.');
              });
  
          } else {
              alert("elementForMenuLaunch '" + elementId + "'is not found!");
          }
      };
  
      //function getMousePos() {
      //}
  
      function getDocScrollPos() {
          var x = document.body.scrollLeft ||
                  document.documentElement.scrollLeft ||
                  window.pageXOffset || 0,
              y = document.body.scrollTop ||
                  document.documentElement.scrollTop ||
                  window.pageYOffset || 0;
          return [x, y];
      }
  
      function isIE(userAgent) {
          userAgent = userAgent || navigator.userAgent;
          return userAgent.indexOf("MSIE ") &gt; -1 || userAgent.indexOf("Trident/") &gt; -1;
      }
  
      function navigateTo(e) {
          console.log("hideMenu entered");
          hideMenu();
          var href = jQuery.data(this, 'data-href');
          console.log("called navigateTo " + href);
          window.location.href = href;  
      }
  
  
  
  
      function setMenuInner(sMenuId, lPixelLeft, lPixelTop, jsonItems) {
          //console.log("setMenu entered");
          if (sMenuId !== '') {
              var jqMenu = $('#' + sMenuId);
  
              if (jqMenu) {
                  jqMenu.empty();
  
  
                  //jQuery.data(document.body, 'data-activeMenu', sMenuId);
  
                  //hideMenu();
                  //$('body').click(hideMenu());
  
                  var lItemCount = jsonItems.length;
                  for (var i = 0; i &lt; lItemCount; i++) {
                      var jqListItemNew = $("&lt;li data-href='" + jsonItems[i].href + "'&gt;&lt;/li&gt;").appendTo(jqMenu);
                      var jqAnchor = $("&lt;a href='#'&gt;&lt;/a&gt;" ).appendTo(jqListItemNew);
                      var jqSpan = $("&lt;span data-href='" + jsonItems[i].href + "'&gt;" + jsonItems[i].itemText + "&lt;/span&gt;").appendTo(jqAnchor);
                      jqSpan.data('data-href', jsonItems[i].href);
                      jqSpan.click(navigateTo);
                  }
                  $('body').data('data-activeMenu', '');
                  if ($('body').data('data-activeMenu') != '') {
                      alert('failed to clear data-activeMenu on Body');
                  };
                  //[Line 130 in fiddle screen]$('body').click(hideMenu)
                  $('body').data('data-activeMenu', sMenuId);
                  if ($('body').data('data-activeMenu') != sMenuId) {
                      alert('failed to set data-activeMenu on Body');
                  };
  
  
                  jqMenu.css('position', 'absolute');
                  jqMenu.css('left', lPixelLeft + 'px');
                  jqMenu.css('top', lPixelTop + 'px');
                  jqMenu.css('display', 'block');
              } else {
                  alert("menu (ul) id '" + sMenuId + "' not found!");
              }
  
          } else {
              alert("menu id '" + sMenuId + "' is null!");
          }
      }
  
      function wireUpButton() {
          var sButtonId = '#button_ShowMenu';
          var buttonMoveList = $(sButtonId);
          if (buttonMoveList) {
              buttonMoveList.click(function () {
                  setMenuInner('my_custom_menu', 400, 100, dynamicMenu());
              });
          } else {
              alert("button element id '" + sButtonId + "' not found!");
          }
  
  
      };
  });
  </code></pre>