一个 input 框,可以有选中状态:focus-within
,比如这样:
有些时候,我们希望一个 div 等其他只读元素也可以有这样的效果,鼠标点一下,可以这样选中。但是默认情况下,这个是办不到的。
首先,理解 :focus-within
:focus-within
是一个 CSS 伪类,当元素或其子元素获得焦点时,会匹配该元素。
也就是说,让 div 获取到焦点就可以。
让 div 获得焦点
1、添加 tabindex 属性
这个非常简单,为 div 添加 tabindex 属性,使其能够获得焦点,然后通过 :focus 伪类模拟 :focus-within 的效果。
<template>
<div
class="input-container"
tabindex="0" <!-- 使 div 可聚焦 -->
>
<span>只读内容</span>
</div>
</template>
就这样就可以实现了。
优点:
- 简单直接,无需额外逻辑。
- 纯 CSS 实现。
缺点:
- 只能模拟 div 本身的焦点状态,无法处理子元素的焦点状态。
2、使用子元素作为焦点目标
在 div 内部放置一个可聚焦的子元素(如 button 或 span),并通过 JavaScript 监听子元素的焦点事件,动态为 div 添加样式。
<template>
<div
class="input-container"
:class="{ focused: isFocused }"
>
<span tabindex="0" @focus="handleFocus" @blur="handleBlur">只读内容</span>
</div>
</template>
<script setup>
import { ref } from "vue";
const isFocused = ref(false);
const handleFocus = () => {
isFocused.value = true;
};
const handleBlur = () => {
isFocused.value = false;
};
</script>
优点:
- 更灵活,可以处理子元素的焦点状态。
- 适用于复杂场景。
缺点:
- 需要额外的 JavaScript 逻辑。
3、使用 contenteditable 实现可编辑 div
还可以通过使用 contenteditable 属性实现。本质上这种方式就是将一个 div 变成一个可选中的文本框,它已经就可以被选中了。
<template>
<div
class="input-container"
contenteditable="true" <!-- 添加这个属性 -->
>
只读内容
</div>
</template>
优点:
- 支持交互操作(如复制、粘贴)。
- 纯 CSS 实现。
缺点:
- 内容可编辑。
文章评论