ReactJS中span标签onMouseUp事件无效,如何实现选中文本传递?
解决span标签下onMouseUp获取选中文本的问题
问题描述
我有两个div,希望通过onMouseUp事件将选中的文本传递到另一个div中。目前使用<textarea>标签时该功能可以正常工作,但换成<span>标签后就失效了,请问是否有其他实现方法?
解决方案
核心原因是<span>这类普通文本元素没有value、selectionStart、selectionEnd这些表单元素特有的属性,所以原来针对<textarea>的代码无法生效。改用浏览器通用的选中文本API即可解决问题:
修改后的完整代码
import React from "react"; import { Box, Grid, TextField } from "@material-ui/core"; import { useState } from "react"; const SendSelectedText = () => { const [label1, setLabel1] = useState(""); const handleMouseUp = () => { // 获取页面上选中的文本,trim()去除首尾空白 const selectedText = window.getSelection().toString().trim(); setLabel1(selectedText); }; return ( <> <Box className="sendSelectedTextPage"> <Grid container spacing={3}> <Grid item xl={6} lg={6} md={6}> <span onMouseUp={handleMouseUp} style={{ width: "100%", height: "200px", display: "block", // 让span支持宽高设置(默认inline不支持) overflow: "auto", // 内容超出时显示滚动条 border: "1px solid #eee", // 可选:添加边框方便识别区域 padding: "8px" }} > The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many … The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many … </span> </Grid> <Grid item xl={6} lg={6} md={6}> <TextField variant="outlined" size="small" label="Label One" value={label1} multiline rows={3} className="sendSelectedTextPageInput" /> </Grid> </Grid> </Box> </> ); }; export default SendSelectedText;
关键修改点说明
- 替换获取选中文本的方式:用
window.getSelection().toString()替代依赖e.target.value的代码,这是浏览器提供的通用API,支持所有可选中的文本元素。 - 修复span样式问题:给span添加
display: block,使其支持自定义宽高;添加overflow: auto优化长文本的显示体验。 - 规范变量命名:将
setlabel1改为setLabel1,符合React驼峰命名习惯。
可选优化:限制仅获取当前span内的文本
如果需要确保只捕获当前span范围内的选中文本,可修改事件处理函数:
const handleMouseUp = (e) => { const selection = window.getSelection(); if (!selection.rangeCount) return; const range = selection.getRangeAt(0); // 判断选中文本的根容器是否在当前span内 if (e.target.contains(range.commonAncestorContainer)) { const selectedText = selection.toString().trim(); setLabel1(selectedText); } };
内容的提问来源于stack exchange,提问作者Rohit Verma
相关产品推荐
相关产品推荐

