JS 在文本框任意位置插入一对括号,怎么能让光标停留在括号中间?

2019-11-20 09:45:06 +08:00
 lisisi

效果类似输入法,点击插入按钮,在文本框中的当前位置,插入一对括号,然后让光标停留在光标中,方便用户输入。

<a class="btn" onclick="addBrackets()">点击插入括号</a>
<textarea id="objText">请在这里输入内容...</textarea>

<script type="text/javascript">
    function addBrackets(){
        var obj = document.getElementById('objText');
        obj.value = obj.value + "()";
        obj.focus();
    }
</script>

遇到两个问题:一是任意位置插入怎么计算当前位置?另外一个是要怎么把光标 focus 在刚刚插入的这对括号()中间位置?

4079 次点击
所在节点    JavaScript
8 条回复
fancy111
2019-11-20 09:56:07 +08:00
不需要计算位置,监听输入事件,当左括号按下的时候,自动补充右括号,然后自动按一次←左键即可。
IsaacYoung
2019-11-20 10:07:34 +08:00
我记得 Range 对象可以做这个。楼主可以搜一下
15651980765
2019-11-20 10:24:21 +08:00
先 mark,有时间再看。
learnshare
2019-11-20 10:33:47 +08:00
从交互上讲不建议这么做,并不符合输入的预期,会给用户带来困扰(个别输入法自作多情而已)

实现的话,可以考虑劫持某个输入事件,判断最后输入的两个字符,如果是一对括号,则多补一个左箭头
rabbbit
2019-11-20 10:43:56 +08:00
<input>
<button>插入</button>

let input = document.querySelector('input')
let btn = document.querySelector('button')

let selectionStart;
input.addEventListener('blur', function(event) {
selectionStart = input.selectionStart;
})
btn.addEventListener('click', function(event) {
if (!selectionStart) {
return;
}
input.value = input.value.slice(0, selectionStart)
+ '()'
+ input.value.slice(selectionStart);
input.focus();
input.selectionStart = selectionStart + 1;
input.selectionEnd = selectionStart + 1;
})
xuxuzhaozhao
2019-11-20 10:48:30 +08:00
@rabbbit 牛批!
lisisi
2019-11-20 12:24:58 +08:00
@rabbbit 很赞!#5 楼很精炼,其他地方的实现都比这个啰嗦
lisisi
2019-11-20 20:10:09 +08:00
@rabbbit 出现一个疑问:我把上面 JS 部分放进一个 onclick() 函数之后,反复点两三次,就会一次会插入多个双括号。这是什么原因导致的?

JS 部分的代码没改动,只是放进了一个 onclick="addBrackets()" 中,就会出现插入多个双括号的情况:

<input>
<button onclick="addBrackets()">插入</button>

<script type="text/javascript">
function addBrackets() {
let input = document.querySelector('input')
let btn = document.querySelector('button')

let selectionStart;
input.addEventListener('blur', function(event) {
selectionStart = input.selectionStart;
})
btn.addEventListener('click', function(event) {
if (!selectionStart) {
return;
}
input.value = input.value.slice(0, selectionStart)
+ '()'
+ input.value.slice(selectionStart);
input.focus();
input.selectionStart = selectionStart + 1;
input.selectionEnd = selectionStart + 1;
})
}
</script>

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/621255

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX