diff --git a/CHANGELOG.md b/CHANGELOG.md index 918b6628..511c2669 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ * A `select`'s phantom mousedown is no longer treated as an outside click (fixes #744) * A re-dispatched layer click now targets the element actually clicked (fixes #771) * Guard against undefined `e.data` in the contextmenu handler (fixes #777) +* Clicking on after the menu was destroyed no longer throws with `useModal: false` (fixes #805) #### Documentation diff --git a/src/jquery.contextMenu.js b/src/jquery.contextMenu.js index 5f77c0d9..da8c4636 100644 --- a/src/jquery.contextMenu.js +++ b/src/jquery.contextMenu.js @@ -739,8 +739,20 @@ // if the click closing is done through windwow event listener rather than a transparent layer if (!root.$layer) { + // There may be no menu left to hide at all: this listener + // outlives the menu it was registered for, so the menu can + // already be gone by the time the next click arrives - a + // `build` menu empties its own options object once it has + // finished hiding (see op.hide()), and a `hide` event + // handler calling $(selector).contextMenu('destroy') tears + // it down outright. `$menu` is left either dropped + // altogether or as an empty jQuery object, and the latter + // used to throw on the $menu[0] dereference below. + // See https://github.com/swisnl/jQuery-contextMenu/issues/805 + var menuIsGone = !root.$menu || !root.$menu.length; + target = document.elementFromPoint(x - $win.scrollLeft(), y - $win.scrollTop()); - if (root.$menu === null || typeof root.$menu === 'undefined' || (!root.$menu[0].contains(target) && !isWithinDetachedSubmenus(root, target))) { + if (menuIsGone || (!root.$menu[0].contains(target) && !isWithinDetachedSubmenus(root, target))) { // Choosing an option from a native