js 使用contenteditable属性模拟富文本框的时候如何定位光标到指定位置

一般情况下,我们需要使用一个类似富文本的功能,contenteditable是最轻量好用的功能,但是有时候我们希望页面跳转进来的时候。通过外部组件传入的关键字,跳转到该关键字后面的位置,如下图
比如传入c# 的时候,光标自然定位到c#后面

img


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <style>#edit{height:100px;width:500px;border:1px solid red;}</style>
</head>
<body>
    <div id="edit" style="white-space: pre" contenteditable>java
c#
c++
    </div>
    <input type="text" id="key-word" value="c#"/>
    <button id="cursor-btn">设置光标位置</button>

    <script>
        function cursorAt(el, index) {
            el.focus();
            getSelection().setPosition(el.firstChild, index);
        }
        let edit = document.getElementById('edit');
        let keyWord = document.getElementById('key-word');
        let cursorBtn = document.getElementById('cursor-btn');
        cursorBtn.onclick = function() {
            debugger
            let index = edit.innerText.indexOf(keyWord.value) + keyWord.value.length;
            cursorAt(edit, index);
        }
    </script>
</body>
</html>

img

可以根据关键字定位到C#的下标号,再进行定位吧

<div contenteditable="true" id="contenteditablediv" style="white-space: pre">
    1. java
    2. c#
    4. test
    3. c++
</div>
<script>
    let p = document.getElementById('contenteditablediv')
    let s = window.getSelection()
    let r = document.createRange()
    let focusText = new URLSearchParams(window.location.search).get('focusText');
    let point = focusText ? p.innerText.indexOf(focusText) + focusText.length : p.innerText.length;
    r.setStart(p.firstChild, point)
    r.setEnd(p.firstChild, point)
    s.removeAllRanges()
    s.addRange(r)
</script>