【扩展】div获取焦点或可编辑

/**
 * @description 设置光标位置
 */
export const setCurrentCursorPosition = (editableElement: HTMLElement, position: number) => {
    return new Promise(async resolve => {
        if (position >= 0) {
            const selection = window.getSelection();

            const range = await createRange(editableElement, { count: position });
            if (range) {
                range.collapse(false);
                selection.removeAllRanges();
                selection.addRange(range);
            }
        }
        resolve(void 0);
    });
};

/**
 * @description 判断光标 isStart isEnd
 */
export const getCursorInfo = (editableElement: HTMLElement): Promise<{ isStart?: boolean; isEnd?: boolean }> => {
    return new Promise(resolve => {
        const result: { isStart?: boolean; isEnd?: boolean } = {};

        //  获取当前的 cursor  位置
        const range = window.getSelection().getRangeAt(0);
        const preRange = document.createRange(); // 创建一个新的范围来处理光标之前的文本
        preRange.selectNodeContents(editableElement); // 有这个范围选择可编辑 div 的全部内容
        preRange.setEnd(range.startContainer, range.startOffset); // 将此范围的终点设置为游标的起始点

        const thisText = preRange.cloneContents(); // 获取此范围的内容(光标前的文本)
        result.isStart = thisText.textContent.length === 0; // 如果文本的长度为0, 我们就在div的开头.

        const postRange = document.createRange(); // 在游标后冲洗并重复文本, 以确定我们是否结束.
        postRange.selectNodeContents(editableElement);
        postRange.setStart(range.endContainer, range.endOffset);
        const nextText = postRange.cloneContents();
        result.isEnd = nextText.textContent.length === 0;
        resolve(result);
    });
};

/**
 * @description 获取光标当前位置, element 是可编辑元素
 */
export const getCursorPosition = (element: HTMLElement): Promise<number> => {
    return new Promise(resolve => {
        let caretOffset = 0;
        if (typeof window.getSelection !== 'undefined') {
            if (window.getSelection().rangeCount > 0) {
                // 选中的区域
                const range = window.getSelection().getRangeAt(0);
                const preCaretRange = range.cloneRange(); // 克隆一个选中区域
                preCaretRange.selectNodeContents(element); // 设置选中区域的节点内容为当前节点
                preCaretRange.setEnd(range.endContainer, range.endOffset); // 重置选中区域的结束位置
                caretOffset = preCaretRange.toString().length;
            }
        }
        resolve(caretOffset);
    });
};

/**
 * @description 在指定位置插入 htmlStr
 */
export const insertHtmlToEditAble = (element: HTMLElement, htmlStr: string) => {};

/**
 * @description 向目标字符串指定位置插入字符串,返回一个新的字符串
 */
export const insertChatToString = (originString: string, index: number, newString: string) => {
    const str = originString + '';
    return str.slice(0, index) + newString + str.slice(index);
};
原文地址:https://www.cnblogs.com/mailyuan/p/14518013.html