在用户选择之外检测鼠标右键(突出显示)

时间:2015-07-30 09:33:38

标签: javascript html

让我们说用户在页面上选择了一些东西(文字/图像/任何东西),然后他点击了鼠标右键。有没有办法检测他是在选择之外还是在其中点击?

2 个答案:

答案 0 :(得分:1)

经过多次尝试*,我认为没有干净的解决方案。

我终于想出了jstonne' answer 的调整(这本身就是MikeB {{3}的调整在同一个线程上)可以满足您的需求。

它意味着右键单击(简单部分)获取当前选择的Range,然后检查事件的目标节点是否在此范围内(棘手部分)。遗憾的是,没有简单的方法来获取Range对象中包含的节点,因此我们必须遍历Range.startContainerRange.endContainer之间的节点。

* 甚至一个暗示range.extractContents()和MutationObservers

注意:

  • 由于Chrome在我们右键单击时似乎为我们选择了新的范围,因此如果您右键单击文本,它将始终返回true。
  • 当您选择img标记时,您实际上是在元素之前和之后选择textNodes,因此如果您选择下面示例中的第一个图像,并右键单击{ {1}}文字,它将返回true。但是如果你对第二张图片进行相同的测试,那就不会,因为文本被包装成Some Dummy Text元素。
  • 可能还有很多其他警告(取决于浏览器,操作系统等)
    
    
    <span>
    &#13;
    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 do anything
    	if(range.collapsed) return;
    	// Firefox allows us to get the real node we clicked on
    	var result = isTargetInRange(range, event.explicitOriginalTarget, event.target);
    	p.innerHTML= 'clicked in the 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;
        for (node = start.parentNode; node; node = node.parentNode)
        {
        	// our target is an element
        	if(!nodeTarget && elementTarget === node ){
        		result=true;
        		break;
        		}
            nodes.push(node);
            if (node == commonAncestor)
                break;
        }
        nodes.reverse();
    
        // walk children and siblings from start until end is found
        for (node = start; node; node = getNextNode(node))
        {
    		// our target can be a textNode
    		if((nodeTarget && nodeTarget === node) || (!nodeTarget && elementTarget === node)){
    			result=true;
    			break;
    			}
            if (node == end)
                break;
        }
        return result;
    };
    
    document.addEventListener('contextmenu', isInsideSelection, false);
    &#13;
    #result{position: fixed; bottom:0;right:0}
    &#13;
    &#13;
    &#13;

答案 1 :(得分:0)

嗯,我不知道直接答案,但你可以试试这个:

1-在第一次点击中获取x1 = clientX和y1 = clientY

2- on mouseup获取x2 = clientX和y2 = ClientY

右键点击右键,检查客户端X和客户端Y是否在我们得到的1-和2-(带角x1,y1,x2,y2的矩形)中

代码:

var x1,x2,y1,y2;
var selected = false;
document.onmousedown = function(e){
...
}
document.onmouseup = function(e){
    x2 = e.clientX;
    y2 = e.clientY;
    selected = true;
}

http://jsfiddle.net/htpfwwgy/