如何禁用文本选择高亮显示

如何禁用文本选择高亮显示

技术背景

在前端开发中,有时我们需要禁用文本的选择高亮显示,例如在一些按钮、可拖动元素或不想让用户复制内容的区域。user-select 属性原本在 CSS 3 中被提出后又被放弃,现在在 CSS UI Level 4 中再次被提议,不过目前还处于标准化过程中。

实现步骤

CSS 方法

  1. 通用 CSS 类
    1
    2
    3
    4
    5
    6
    7
    8
    .noselect {
    -webkit-touch-callout: none; /* iOS Safari */
    -webkit-user-select: none; /* Safari */
    -khtml-user-select: none; /* Konqueror HTML */
    -moz-user-select: none; /* Old versions of Firefox */
    -ms-user-select: none; /* Internet Explorer/Edge */
    user-select: none; /* Non-prefixed version, currently supported by Chrome, Edge, Opera and Firefox */
    }
    在 HTML 中使用:
    1
    2
    3
    4
    5
    6
    <p>
    Selectable text.
    </p>
    <p class="noselect">
    Unselectable text.
    </p>
  2. 特定元素选择:如果想禁用除 <p> 元素外的所有文本选择,可以这样写:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    * {
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: -moz-none;
    -o-user-select: none;
    user-select: none;
    }

    p {
    -webkit-user-select: text;
    -khtml-user-select: text;
    -moz-user-select: text;
    -o-user-select: text;
    user-select: text;
    }
  3. 保持光标静态:为了让用户感觉文本不可选,可以设置光标样式:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    .noselect {
    cursor: default;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    }
  4. SASS 实现:使用 SASS 的 mixin 可以更方便地实现禁用选择:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // Disable selection
    @mixin disable-selection {
    -webkit-touch-callout: none; /* iOS Safari */
    -webkit-user-select: none; /* Safari */
    -khtml-user-select: none; /* Konqueror HTML */
    -moz-user-select: none; /* Firefox */
    -ms-user-select: none; /* Internet Explorer/Edge */
    user-select: none; /* Non-prefixed version, currently supported by Chrome and Opera */
    }

    // No selectable element
    .no-selectable {
    @include disable-selection;
    }
    在 HTML 中使用:
    1
    <div class="no-selectable">TRY TO HIGHLIGHT. YOU CANNOT!</div>

JavaScript 方法

对于旧版本的 Internet Explorer 和 Opera,需要使用 unselectable 属性:

1
2
3
4
5
6
7
8
9
10
11
12
function makeUnselectable(node) {
if (node.nodeType == 1) {
node.setAttribute("unselectable", "on");
}
var child = node.firstChild;
while (child) {
makeUnselectable(child);
child = child.nextSibling;
}
}

makeUnselectable(document.getElementById("foo"));

在 HTML 中使用:

1
<div id="foo" unselectable="on" class="unselectable">...</div>

核心代码

CSS 通用禁用选择类

1
2
3
4
5
6
7
8
.noselect {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}

JavaScript 递归设置 unselectable 属性

1
2
3
4
5
6
7
8
9
10
function makeUnselectable(node) {
if (node.nodeType == 1) {
node.setAttribute("unselectable", "on");
}
var child = node.firstChild;
while (child) {
makeUnselectable(child);
child = child.nextSibling;
}
}

最佳实践

  • 使用现代浏览器支持的属性:优先使用 user-select 属性,同时添加浏览器前缀以确保兼容性。
  • 结合 JavaScript 和 CSS:对于旧版本浏览器,使用 JavaScript 来设置 unselectable 属性。
  • 使用预处理器:如 SASS 或 Less,使用 mixin 来简化代码。

常见问题

  1. 浏览器兼容性问题user-select 属性还在标准化过程中,不同浏览器的实现可能存在差异,并且未来浏览器可能会改变对它的支持。可以参考 Can I use 来了解浏览器兼容性。
  2. WebKit 复制问题:即使设置了 user-select: none,WebKit 浏览器仍然允许在选择周围元素时复制文本。可以尝试将 user-select 的值设置为 all 来强制选择整个元素。
  3. 事件处理:在添加新元素时,可能需要重新运行递归设置 unselectable 属性的函数。可以通过添加 mousedown 事件处理程序来避免这个问题。

如何禁用文本选择高亮显示
https://119291.xyz/posts/2025-05-07.how-to-disable-text-selection-highlighting/
作者
ww
发布于
2025年5月7日
许可协议