选择下拉选项后如何让textarea获焦并将光标置于新增文本后?
我明白你遇到的问题了——在通过下拉框选择内容插入到textarea后,你想让光标自动定位到新增文本的末尾,但直接调用focus()好像没生效,不过按钮点击事件里的focus()却能正常工作。这其实是因为你只调用了focus(),但没有手动设置光标位置,再加上下拉框的事件触发顺序干扰,导致光标没跑到预期位置。
问题根源分析
- 仅调用
focus()只会让textarea获得焦点,但不会自动调整光标到新增文本的末尾,默认光标位置会回到文本开头或原选中位置。 - 下拉框的
blur事件(也就是up函数)会立即重置下拉框状态,可能在光标设置完成前抢走焦点,导致设置失效。
解决方案:调整光标位置+优化事件逻辑
下面是修改后的完整代码,我标注了关键修改点:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <style> .tail { position: absolute; } textarea { min-width: 250px; min-height: 100px; } </style> <!-- #MAIN PANEL --> <div id="main" role="main"> <!-- RIBBON --> <div id="ribbon"> <!-- breadcrumb --> <ol class="breadcrumb"> <li>Home</li> </ol> </div> <!-- col --> <div class="col-xs-12 col-sm-7 col-md-7 col-lg-4"> <h1 class="page-title txt-color-blueDark"></h1> <div class="clearfix"></div> <textarea id="example"></textarea> <div class="tail" hidden> <select id="select"> <option style="display: none;">Please select one</option> <option value="USER_NAME}">First and Last Name</option> <option value="WO_NO}">Work Order Number</option> <option value="PROD}">Product Name and Size</option> <option value="PROJECT}">Project Name</option> <option value="MACHINE}">Machine Name</option> </select> </div> <div> <input type="button" value="CLICK ME!" id="click"> </div> </div> </div> <script src="https://rawgit.com/Codecademy/textarea-helper/master/textarea-helper.js"></script> <script> function append_textarea(textarea, select, div_for_select) { $(textarea).on('keyup paste cut mouseup', function (event) { var contentHeight = $(this).textareaHelper('height'); $(this).height(contentHeight); var obj = $(this).textareaHelper('caretPos'); var left = obj.left + 15; var top = obj.top + 50; if (event.which === 219) { $(div_for_select).attr('style', 'top: ' + top + 'px;' + ' left: ' + left + 'px;').fadeIn(); openDropdown(select); } else if (event.which === 221) { $(div_for_select).fadeOut('slow'); } }); // 核心修改1:插入文本后手动设置光标位置 $(div_for_select).on('keydown click', function (event) { if (event.which === 13 || event.which === 1) { var $txt = $(textarea); var caretPos = $txt[0].selectionStart; var textAreaTxt = $txt.val(); var txtToAdd = $(select).val(); // 计算新光标位置:原位置 + 新增文本长度 var newCaretPos = caretPos + txtToAdd.length; // 更新文本内容 $txt.val(textAreaTxt.substring(0, caretPos) + txtToAdd + textAreaTxt.substring(caretPos)); // 先让textarea获得焦点 $txt.focus(); // 强制把光标定位到新增文本末尾 $txt[0].selectionStart = $txt[0].selectionEnd = newCaretPos; $(this).fadeOut('slow'); // 阻止事件冒泡,避免干扰光标设置 event.stopPropagation(); event.preventDefault(); } }); $(textarea).keyup(); // 核心修改2:延迟重置下拉框,避免抢走焦点 function openDropdown(elementId) { function down() { var pos = $(this).offset(); // remember position var len = $(this).find("option").length; if (len > 20) { len = 20; } $(this).css("position", "absolute"); $(this).css("zIndex", 9999); $(this).offset(pos); // reset position $(this).attr("size", len); // open dropdown $(this).unbind("focus", down); $(this).trigger('focus'); } function up() { // 延迟100ms重置下拉框,确保光标已经设置完成 setTimeout(() => { $(this).css("position", "static"); $(this).attr("size", "1"); // close dropdown $(this).unbind("change", up); }, 100); } $(elementId).focus(down).blur(up).focus(); } } append_textarea('#example', '#select', '.tail'); $('#select').on('click', function () { $('#example').focus(); }); $('#click').on('click', function () { $('#example').focus(); }); </script>
关键修改点说明
- 手动设置光标位置:通过
selectionStart和selectionEnd属性,强制把光标定位到新增文本的末尾,这是单纯调用focus()做不到的。 - 阻止事件冒泡:在插入文本的事件里调用
event.stopPropagation()和event.preventDefault(),避免触发下拉框的blur事件干扰焦点设置。 - 延迟重置下拉框:用
setTimeout延迟执行下拉框的重置逻辑,确保光标已经成功定位后再操作,避免下拉框重置抢走焦点。
这样修改后,你选择下拉框内容插入到textarea后,光标就会自动停在新增文本的后面了~
内容的提问来源于stack exchange,提问作者Angelika Klimek
相关产品推荐
相关产品推荐

