当选择文本时,如何防止 onClick 事件触发?

59

我遇到了一个问题,我需要在单击表格单元格时显示和隐藏divs。然而,我也希望人们能够选择文本并在单元格内复制它而不隐藏信息。

如果必要的话,完全可以更改设计。 :)

这里有一个演示该问题的示例:

http://jsfiddle.net/k61u66ek/1/

这是演示中的HTML代码:

<table border=1>
    <tr>
        <td>
            Information
        </td>
        <td onClick="toggleInfo()">
            <div id="information" style="display:none">
                More information that I want to select without hiding
            </div>
            <div id="clicktoshow">
                Click to show info
            </div>

        </td>
    </tr>
</table>

以下是JavaScript代码:

function toggleInfo() {
    $("#clicktoshow").toggle();
    $("#information").toggle();    
}
任何建议/意见都非常感激!
/Patrik

3
简单的解决方法是使用双击而不是单击。查看http://jsfiddle.net/k61u66ek/2/ - seenukarthi
6个回答

70

一种选择是检查由window.getSelection返回的Selection对象的type

function toggleInfo() {
    var selection = window.getSelection();
    if(selection.type != "Range") {
        $("#clicktoshow").toggle();
        $("#information").toggle();
    }
}

更新

如果你要针对的浏览器在Selection对象上不公开type属性,则可以根据所选择值的长度进行测试:

http://jsfiddle.net/k61u66ek/4/

function toggleInfo() {
    var selection = window.getSelection();
    if(selection.toString().length === 0) {
        $("#clicktoshow").toggle();
        $("#information").toggle();
    }
}

http://jsfiddle.net/k61u66ek/9/

这可以进一步简化为对 toString 的布尔检查:

if(!selection.toString()) {

http://jsfiddle.net/k61u66ek/10/


1
谢谢@t00thy,我已经更新了我的答案,包括在“type”不可用时的解决方案。 - Jamie Dixon
1
这是我的解决方案,通过捕捉鼠标点击时间来实现[http://jsfiddle.net/k61u66ek/15/](http://jsfiddle.net/k61u66ek/15/)。我将点击和复制的时间差设置为200毫秒。也许这会有所帮助。 - t00thy
似乎 toString() 比 type=="Range" 更适合在 IE11 和 Firefox 上使用。 - Sam Jason Braddock
toString()方法在仅选择图像时无法正常工作。现如今,type方法似乎在浏览器上有很好的支持。 - cdauth

12

你可以在点击事件处理程序中检查是否进行了选择:

window.getSelection().toString();

12

简述 JS解决方案

演示:http://jsfiddle.net/5472ja38/

代码(取消文本高亮/选中时的点击事件):

document.getElementById('information').addEventListener('click', (e) => {
  const cellText = document.getSelection();
  if (cellText.type === 'Range') e.stopPropagation();
})

解释

document.getSelection().type 在文档对象级别上检查是否已经高亮显示了任何文本。如果是,则type属性等于“Range”,停止事件传播,这将取消单击切换按钮的更改。

摘自MDN

DOMString描述当前选择的类型。可能的值包括:

None:当前没有进行任何选择。

Caret:选择已折叠(即插入符号放置在某些文本上,但未选择范围)。

Range:已选择范围。


4
你可以使用 mouseupmousedownmousemove 事件来实现此功能:

演示

var isDragging = false;
$("#clickshow")
.mousedown(function() {
    isDragging = false;
})
.mousemove(function() {
    isDragging = true;
 })
.mouseup(function() {
    var wasDragging = isDragging;
    isDragging = false;
    if (!wasDragging) {
        $("#information").toggle();
        $("#clicktoshow").toggle();
    }
});

来源


3

另一种方法是使用选择的isCollapsed属性。根据MDN,如果选择的起始点和结束点相同(对于单击而言是正确的),它会返回true:

document.getElementById('information').addEventListener('click', (e) => {
    if (!window.getSelection().isCollapsed) {
        return;
    }

    // do something here
});


0
你可以检查 'information' div 是否被切换:
function toggleInfo() {
    if(document.getElementById('information').style.display == 'none'){
         $("#clicktoshow").toggle();
         $("#information").toggle();
   } else { 
       // do nothing
   }
}

请检查这个Fiddle


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接