You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 19:40:57