双击后防止文本选择

Posted

技术标签:

【中文标题】双击后防止文本选择【英文标题】:Prevent text selection after double click 【发布时间】:2010-10-27 04:50:19 【问题描述】:

我正在我的网络应用程序中处理跨度上的 dblclick 事件。一个副作用是双击会选择页面上的文本。如何防止这种选择发生?

【问题讨论】:

【参考方案1】:

顺风 CSS:

<div class="select-none ...">
  This text is not selectable
</div>

【讨论】:

【参考方案2】:

我知道这是一个老问题,但它在 2021 年仍然完全有效。但是,我在答案方面缺少的是对 Event.stopPropagation() 的任何提及。

OP 要求dblclick 事件,但据我所知,pointerdown 事件也会出现同样的问题。在我的代码中,我注册了一个监听器,如下所示:

this.addEventListener("pointerdown", this._pointerDownHandler.bind(this));

监听器代码如下:

_pointerDownHandler(event) 
  // Stuff that needs to be done whenever a click occurs on the element

在我的元素上快速单击多次会被浏览器解释为双击。根据您的元素在页面上的位置,双击将选择文本,因为这是给定的行为。

可以通过在侦听器中调用Event.preventDefault() 来禁用该默认操作,这确实解决了问题,至少在某种程度上。

但是,如果您在一个元素上注册一个监听器并编写相应的“处理”代码,那么您最好吞下该事件,这正是Event.stopPropagation() 所确保的。因此,处理程序如下所示:

_pointerDownHandler(event) 
  event.stopPropagation();
  // Stuff that needs to be done whenever a click occurs on the element

因为我的元素已经使用了该事件,所以层次结构中更靠前的元素不知道该事件,也不会执行它们的处理代码。

如果你让事件冒泡,层次结构中较高的元素全部执行它们的处理代码,但Event.preventDefault() 告诉你不要这样做,这对我来说比阻止从一开始就冒泡的事件。

【讨论】:

【参考方案3】:

如果您使用的是 Vue JS,只需将 @mousedown.prevent="" 附加到您的元素,它就会神奇地消失!

【讨论】:

嗯,你确定吗?你有没有测试过它,你在什么浏览器上运行测试,因为我有 chrome,它运行良好。【参考方案4】:
function clearSelection() 
    if(document.selection && document.selection.empty) 
        document.selection.empty();
     else if(window.getSelection) 
        var sel = window.getSelection();
        sel.removeAllRanges();
    

您还可以将这些样式应用于所有非 IE 浏览器和 IE10 的 span:

span.no_selection 
    user-select: none; /* standard syntax */
    -webkit-user-select: none; /* webkit (safari, chrome) browsers */
    -moz-user-select: none; /* mozilla browsers */
    -khtml-user-select: none; /* webkit (konqueror) browsers */
    -ms-user-select: none; /* IE10+ */

【讨论】:

有什么方法可以真正阻止选择,而不是事后删除选择?此外,为了更好的可读性,您的第二个 if 语句可以在 else if 中。 最好使用 -webkit- 前缀(这是基于 Webkit 的浏览器的首选前缀)以及 -moz-(和 -khtml-,如果您有大量 Konqueror 用户)。 现在可以在 IE10 中使用 -ms-user-select: none; 参见 blogs.msdn.com/b/ie/archive/2012/01/11/… @PaoloBergantino @TimHarper:就使用库的 javascript 解决方案而言,当然可以。不太清楚为什么这值得一票否决。 在双击时禁用选择和完全禁用是有区别的。第一个增加了可用性。第二个减少。【参考方案5】:

对于那些正在寻找 Angular 2+ 解决方案的人。

您可以使用表格单元格的mousedown 输出。

<td *ngFor="..."
    (mousedown)="onMouseDown($event)"
    (dblclick) ="onDblClick($event)">
  ...
</td>

并防止detail &gt; 1

public onMouseDown(mouseEvent: MouseEvent) 
  // prevent text selection for dbl clicks.
  if (mouseEvent.detail > 1) mouseEvent.preventDefault();


public onDblClick(mouseEvent: MouseEvent) 
 // todo: do what you really want to do ...

dblclick 输出继续按预期工作。

【讨论】:

【参考方案6】:

仅在双击后防止文本选择:

您可以使用MouseEvent#detail 属性。 对于 mousedown 或 mouseup 事件,它是 1 加上当前点击次数。

document.addEventListener('mousedown', function (event) 
  if (event.detail > 1) 
    event.preventDefault();
    // of course, you still do not know what you prevent here...
    // You could also check event.ctrlKey/event.shiftKey/event.altKey
    // to not prevent something useful.
  
, false);

见https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail

【讨论】:

这太棒了!适用于 Firefox 53。 这应该是公认的答案。这里的所有其他内容都阻止了任何鼠标选择(或更糟),而不是回答 OP 的问题“双击后防止文本选择 也可以在 Chrome 中使用 使用(event.detail === 2) 真正防止仅双击(而不是三次单击等) @Catalin,因为似乎dblclickmouseup 之后触发,而选择发生在mousedown 之后【参考方案7】:

FWIW,我将user-select: none 设置为那些我不想在双击父元素的任意位置时以某种方式选择的子元素的父元素。它有效!很酷的是contenteditable="true",文本选择等仍然适用于子元素!

比如:

<div style="user-select: none">
  <p>haha</p>
  <p>haha</p>
  <p>haha</p>
  <p>haha</p>
</div>

【讨论】:

谢谢,style="user-select: note" 到处都解决了我试图解决的问题 :) 不错的纯 CSS 解决方案,适用于您基本上不希望文本可选择的情况。谢谢!【参考方案8】:

如果您试图完全阻止通过任何方法以及仅通过双击选择文本,您可以使用user-select: none css 属性。我在 Chrome 68 中进行了测试,但根据 https://caniuse.com/#search=user-select 它应该可以在其他当前普通用户浏览器中使用。

在行为上,在 Chrome 68 中,它由子元素继承,并且不允许选择元素包含的文本,即使选择了围绕并包含元素的文本。

【讨论】:

【参考方案9】:

我遇到了同样的问题。我通过切换到&lt;a&gt; 并添加onclick="return false;" 解决了这个问题(这样点击它就不会在浏览器历史记录中添加新条目)。

【讨论】:

【参考方案10】:

旧线程,但我想出了一个我认为更干净的解决方案,因为它不会禁用每个甚至绑定到对象,并且只会阻止页面上随机和不需要的文本选择。这很简单,对我来说效果很好。 这是一个例子;当我在具有“右箭头”类的对象上单击几次时,我想阻止文本选择:

$(".arrow-right").hover(function()$('body').css(userSelect: "none");, function()$('body').css(userSelect: "auto"););

HTH!

【讨论】:

【参考方案11】:

在纯javascript中:

element.addEventListener('mousedown', function(e) e.preventDefault(); , false);

或者使用 jQuery:

jQuery(element).mousedown(function(e) e.preventDefault(); );

【讨论】:

是的,我用它来解决我遇到的同样的问题 (+1),除了 return false 使用 event.preventDefault() 它不会杀死你在 mousedown 上可能拥有的任何其他处理程序。 这会破坏页面上的 textarea 元素 :( @johnktejik 仅当 element 是文本区域时,是的。 希望将此事件处理程序分配给“dblclick”——但这不起作用,这太奇怪了。使用“mousedown”,您当然也无法通过拖动来选择文本。【参考方案12】:

为了防止 IE 8 CTRL 和 SHIFT 单击单个元素上的文本选择

var obj = document.createElement("DIV");
obj.onselectstart = function()
  return false;

防止在文档上选择文本

window.onload = function()
  document.onselectstart = function()
    return false;
  

【讨论】:

【参考方案13】:

一个简单的 Javascript 函数,使页面元素内的内容无法选择:

function makeUnselectable(elem) 
  if (typeof(elem) == 'string')
    elem = document.getElementById(elem);
  if (elem) 
    elem.onselectstart = function()  return false; ;
    elem.style.MozUserSelect = "none";
    elem.style.KhtmlUserSelect = "none";
    elem.unselectable = "on";
  

【讨论】:

【参考方案14】:

或者,在 Mozilla 上:

document.body.onselectstart = function()  return false;  // Or any html object

在 IE 上,

document.body.onmousedown = function()  return false;  // valid for any html object as well

【讨论】:

此解决方案根本不允许选择文本。 @jmav 您必须在比document.body 更具体的元素上应用函数覆盖。

以上是关于双击后防止文本选择的主要内容,如果未能解决你的问题,请参考以下文章

Recyclerview在Android中notifyItemChanged后防止触摸事件

调用 reloadData 后防止标头更新?

在jQuery中拖动后防止点击事件

以角度订阅后防止刷新

在jQuery中拖动后防止点击事件

使用 jQuery 在初始 .mousedown() 事件后防止后续触发