花潮论坛

搜索
热搜: 活动 交友 discuz
查看: 14|回复: 0

Textarea回车键的处理

[复制链接]
  • TA的每日心情
    奋斗
    2026-5-26 12:05
  • 签到天数: 1826 天

    [LV.Master]伴坛终老

    3226

    主题

    13万

    回帖

    28万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9

    花潮帅哥鼠牛虎兔龙蛇马羊猴鸡狗猪多彩人生星月交辉奔放热烈海样胸怀春风拂面火热情怀优雅迷人神秘浪漫相遇之美鹰傲苍穹花好月圆紫色情节飞龙在天王者至尊大将风范音画大师天籁妙音共看流星风雨同行我心永远幸福快乐喜乐安康侠骨柔肠心想事成开朗大方花潮管理

    发表于 2026-5-26 12:35 | 显示全部楼层 |阅读模式

    请马上登录,朋友们都在花潮里等着你哦:)

    您需要 登录 才可以下载或查看,没有账号?立即注册

    x
    过去手写的基于 textarea 标签的只能回车键处理极为简洁:
    1. // start 和 end 已事先获取
    2. if (e.key === 'Enter') {
    3.     e.preventDefault();
    4.     const tstr = value.substring(0, end);
    5.     const strAr = tstr.split('\n');
    6.     const target = strAr[strAr.length - 1];
    7.     const indent = '\n' + (target.match(/^\s*/)[0] || '');
    8.     ele.setRangeText(indent);
    9.     ele.selectionStart = end + indent.length;
    10.     ele.selectionEnd = end + indent.length;
    11. }
    复制代码

    但它忽略了一个问题:当辑框里如果有选中文本。

    为了省事,我把上面的代码交给DS,让它帮完善。DS考虑得很周到,它提供的代码可行:
    1. if (e.key === 'Enter') {
    2.     const start = ele.selectionStart;
    3.     const end = ele.selectionEnd;
    4.     const hasSelection = start !== end;
    5.    
    6.     // 如果有选中文本,先删除
    7.     if (hasSelection) {
    8.         ele.setRangeText('', start, end, 'start');
    9.     }
    10.    
    11.     // 获取当前光标位置(删除选中文本后的新位置)
    12.     const currentPos = ele.selectionStart;
    13.     const currentValue = ele.value;
    14.    
    15.     // 获取当前行的缩进
    16.     const textBeforeCursor = currentValue.substring(0, currentPos);
    17.     const lines = textBeforeCursor.split('\n');
    18.     const currentLine = lines[lines.length - 1];
    19.     const indent = '\n' + (currentLine.match(/^\s*/)[0] || '');
    20.    
    21.     // 插入换行和缩进
    22.     ele.setRangeText(indent, currentPos, currentPos, 'end');
    23.    
    24.     // 设置光标到新位置
    25.     const newPos = currentPos + indent.length;
    26.     ele.selectionStart = newPos;
    27.     ele.selectionEnd = newPos;
    28. }
    复制代码
    代码量远远超出我的预期。要保持简洁度,还是用回原来的代码,需要改进一下:

    1. // start 和 end 已事先统一获取
    2. if (e.key === 'Enter') {
    3.     e.preventDefault();
    4.     const tstr = value.substring(0, end);
    5.     const strAr = tstr.split('\n');
    6.     const target = strAr[strAr.length - 1];
    7.     const indent = '\n' + (target.match(/^\s*/)[0] || '');
    8.     ele.setRangeText(indent);
    9.     ele.selectionStart = ele.selectionEnd = end + indent.length - (end - start);
    10. }
    复制代码


    核心在 09 行:编辑框输入光标的位置指定——拿选中文本的光标结束位置 end 减去起始位置 start,这样能够巧妙处理了选中和没有选中文本的状态(不选中时 end - start = 0,选中时重设的光标位置要减去 end - start 的差即回车删掉的选中文本的长度)。

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    小黑屋|手机版|Archiver|服务支持:DZ动力|huachaowang.com Inc. ( 蜀ICP备17032287号-1 )

    GMT+8, 2026-5-26 16:29 , Processed in 0.057999 second(s), 25 queries .

    Powered by Discuz! X3.4

    © 2001-2013 Comsenz Inc.

    快速回复 返回顶部 返回列表