JavaScript:禁用文本选择

103
我正在使用 JavaScript 在我的网站上禁用文字选择。
代码如下:

代码如下:

<script type="text/JavaScript">

function disableselect(e) {
  return false
}

function reEnable() {
  return true
}

document.onselectstart = new Function ("return false")

if (window.sidebar) {
  document.onmousedown = disableselect
  document.onclick = reEnable
}
</script>

类似的脚本可以在这里找到。

在我的本地主机上:所有浏览器(Firefox、Chrome、IE和Safari)都运行良好。

在我的实际网站上:除了 Firefox 之外都正常。

我的问题是:

  1. 是否有人对为什么Firefox在实际网站和本地主机上表现不同有建议。注意:Javascript已启用。

  2. 也许我的脚本太简单了,所以我尝试了以下脚本,结果完全相同。


4
我建议你避免在这种情况下使用JavaScript。只需使用CSS,你可以在此问题中找到更多关于CSS文本选择的信息。 - RienNeVaPlu͢s
第二个脚本可能太旧了。删除!document.all,因为我认为它会破坏fx支持。 - mplungjan
onselectstart在FF中不受支持,而且这是有充分理由的。 - James Daly
12
我讨厌这样的网站。如果我想复制一些文本,我可以打开开发者工具并复制它,所以这只是一种不必要的麻烦。 - uylmz
5
就像 Reek 所说的那样。除非你有非常充分的理由,否则不要这样做。许多人可能只是想选择某些内容来搜索或使用字典查找单词。禁止这样做只会带来麻烦,最终可能会让人们远离你的网站。 - Czechnology
3
首先,我也讨厌那种禁止选中(文字或其他内容)的页面仅仅是为了“好玩”,但我认为这是一个很好的问题,因为有些人确实有想要禁用它的正当理由(例如,在游戏中实现鼠标手势或文本块的拖放)。当然,使用JS来实现这个目的是不好的,但CSS解决方案也存在问题(在一些浏览器中,只有user-select无法运行,需要添加“-vendor-”前缀,如-moz-user-select-webkit-user-select,因此需要将所有可能的变体都设置为“none”才能使其发挥作用)。 - Cyberknight
6个回答

249

只需使用这个CSS方法:

body{
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}

你可以在这里找到相同的答案:如何使用CSS禁用文本选择高亮显示?


11
好的,我会尽力进行翻译。以下是需要翻译的内容:Also add the link from where you found this answer: https://dev59.com/pnRA5IYBdhLWcg3wyRF6请在回答中加入您找到此答案的链接:https://dev59.com/pnRA5IYBdhLWcg3wyRF6 - Ron van der Heijden
1
非常感谢。body 中的 CSS 对于所有情况都有效,但 IE 除外。有没有简洁的 CSS 解决方案也可以解决这个问题呢?现在我正在使用 Js 和 CSS 的组合来覆盖所有浏览器!谢谢。 - arpeggio
  1. 为什么这个答案没有被标记为解决方案?它以最准确简单的方式解决了问题。
  2. 应该提到,这个CSS定义可以在任何HTML元素上实现,而不仅仅是BODY。
- TheCuBeMan
1
@TheCuBeMan “user-select”是一个非标准功能,因此在我看来并不是最佳解决方案。 - ndugger
1
这可能是最好的方法 - 浏览器处理方式不同,因为它很复杂,而且它们都有不同的看法。也就是说,他们希望提供预期的 UX(无选择),同时仍然允许用户选择是否“真的想要”。W3C [draft](http://caniuse.com/#search=user-select)有更多的注释,[caniuse](https://drafts.csswg.org/css-ui-4/#valdef-user-select-none)显示出了极好的支持。浏览器以不同的方式处理它是可以的 - 用户将获得其首选浏览器提供的体验。 - Shawn Erquhart
显示剩余2条评论

37

我正在编写一个滑块用户界面控件,以提供拖动功能。这是我防止用户在拖动时选择内容的方法:

function disableSelect(event) {
    event.preventDefault();
}

function startDrag(event) {
    window.addEventListener('mouseup', onDragEnd);
    window.addEventListener('selectstart', disableSelect);
    // ... my other code
}

function onDragEnd() {
    window.removeEventListener('mouseup', onDragEnd);
    window.removeEventListener('selectstart', disableSelect);
    // ... my other code
}

在您的dom上绑定startDrag

<button onmousedown="startDrag">...</button>

如果您希望静态地禁用所有元素的文本选择,请在元素加载时执行以下代码:

window.addEventListener('selectstart', function(e){ e.preventDefault(); });

      

2
这是最佳解决方案,因为 CSS 解决方案无法处理带有 contenteditable 属性的 div(例如,如果您想在用户使用鼠标调整控件大小时禁用文本选择)。 - mbomb007

11

如需使用JavaScript,请使用以下函数:

function disableselect(e) {return false}
document.onselectstart = new Function (return false)
document.onmousedown = disableselect

使用以下方法来启用选择:

function reEnable() {return true}

并在任何你想要的地方使用这个函数:

document.onclick = reEnable

除了 new Function (return false) 不是有效的 JavaScript 代码之外,只需使用 document.onselectstart = disableselect - amik
@amik 这个怎么样:document.oncontextmenu = new Function("return false;"); 或者这个使用 CSS:<body onselectstart="return false"> - Amir Hassan Azimi
是的,new Function("return false;")可以工作,但与您已经拥有的disableselect相比,过于复杂。onselectstart="return false"也可以工作,但与CSS无关。另外,我也注意到您所回答的其他部分也是错误的——reEnable函数根本无法工作。 - amik
@amik 哈哈,JavaScript 中没有必要的东西,但我们仍然这样做。当然,代码可以重构,但看一下问题,回答问题而不是试图做作业。 - Amir Hassan Azimi
好的,但是SO是一个教育场所,因此我认为提供一个既技术上错误又没有解释的答案不是一个好主意。 - amik
@amik 的评论是合理的,reEnable 不起作用是因为您留下了 onmousedown 和 onselectstart 处理程序。此外,我从不使用 new 创建函数,但也许这只是我的个人习惯。 - Apolo

6
如果你有这样一个HTML页面:
    <body
    onbeforecopy = "return false"
    ondragstart = "return false" 
    onselectstart = "return false" 
    oncontextmenu = "return false" 
    onselect = "document.selection.empty()" 
    oncopy = "document.selection.empty()">

有一种简单的方法可以禁用所有事件:

document.write(document.body.innerHTML)

你将得到HTML内容并丢失其他内容。

这是唯一有效的解决方法,我网站页面上的大部分文本都是由js生成的,可能这就是其他解决方案不起作用的原因! - Joseph Ali

5

你也可以使用“在所有浏览器中都可正常工作,需要JavaScript”的方法:

onselectstart = (e) => {e.preventDefault()}

Example:

onselectstart = (e) => {
  e.preventDefault()
  console.log("nope!")
  }
Select me!


另一个JS的替代方案,是通过测试CSS支持来禁用userSelect或者MozUserSelect(适用于Firefox)。

let FF
if (CSS.supports("( -moz-user-select: none )")){FF = 1} else {FF = 0}
(FF===1) ? document.body.style.MozUserSelect="none" : document.body.style.userSelect="none"
Select me!


纯CSS,相同的逻辑。警告:您需要将这些规则扩展到每个浏览器,这可能会很冗长。

@supports (user-select:none) {
  div {
    user-select:none
  }
}

@supports (-moz-user-select:none) {
  div {
    -moz-user-select:none
  }
}
<div>Select me!</div>


1
在 Safari 版本 14.1.1 上,支持第一个命题但不支持最后一个。 在 Firefox Developer Edition 92.0b3 (64 位) 上,所有命题都被支持。 - Yohan W. Dunon
1
这些似乎在iOS Safari上都不起作用,嗯...我会在13.7上进行测试,并查看其他版本是否有一些额外的进展。 - bnns

0

简单地复制这段文本并将其放置在</body>之前

function disableselect(e) {
  return false
}

function reEnable() {
  return true
}

document.onselectstart = new Function ("return false")

if (window.sidebar) {
  document.onmousedown = disableselect
  document.onclick = reEnable
}

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