javascript - Detect right mouse click outside of the user selection (highlight) -
lets user selected (text/image/anything) on page , clicked right mouse button. there way detect whether clicked outside of selection or inside it?
after lot of tries*, think there no clean solution this.
i come tweak of jstonne's answer (which tweak of mikeb's answer on same thread) may fit needs.
it implies range
of current selection on right click (easy part), , check if target node of event in range (tricky part). sadly, there no easy way nodes contained in range object we've iterate through nodes contained between range.startcontainer
, range.endcontainer
.
*even 1 implying range.extractcontents() , mutationobservers
notes :
- since chrome seems make new range selection when right-click, return true if right click on text.
- when select
img
tag, you're selecting textnodes before , after element, if select first image in below example, , right-click onsome dummy text
text, return true. if same test on second image, won't, since text wrapped<span>
element. - there might lot of other caveats (depending on browser, os etc.)
function isinsideselection(event){ event.preventdefault(); var p = document.queryselector('#result'); p.innerhtml= '' var sel = window.getselection(); if(!sel.rangecount) return; var range = sel.getrangeat(0); // nothing selected : don't if(range.collapsed) return; // firefox allows real node clicked on var result = istargetinrange(range, event.explicitoriginaltarget, event.target); p.innerhtml= 'clicked in target: '+result; } function getnextnode(node) { if (node.firstchild) return node.firstchild; while (node) { if (node.nextsibling) return node.nextsibling; node = node.parentnode; } } function istargetinrange(range, nodetarget, elementtarget) { var start = range.startcontainer.childnodes[range.startoffset] || range.startcontainer; var end = range.endcontainer.childnodes[range.endoffset] || range.endcontainer; var commonancestor = range.commonancestorcontainer; var nodes = []; var node; var result=false; (node = start.parentnode; node; node = node.parentnode) { // our target element if(!nodetarget && elementtarget === node ){ result=true; break; } nodes.push(node); if (node == commonancestor) break; } nodes.reverse(); // walk children , siblings start until end found (node = start; node; node = getnextnode(node)) { // our target can textnode if((nodetarget && nodetarget === node) || (!nodetarget && elementtarget === node)){ result=true; break; } if (node == end) break; } return result; }; document.addeventlistener('contextmenu', isinsideselection, false);
#result{position: fixed; bottom:0;right:0}
<p id="result"></p> <img src="http://lorempixel.com/50/50"/> dummy text <p>some other text</p> <div><img src="http://lorempixel.com/60/60"/><span>with</span> text</div>
Comments
Post a Comment