关于div标签可编辑且插入其它标签的问题

2019-12-17  本文已影响0人  半笑半醉間

落花有意随流水,流水无心蝶恋花

最近在做一个类似下面的功能:

1576576638695.jpg
由于textarea不能满足该要求,所以只有通过div来实现,由于时间关系就不在这里啰嗦了,直接上代码
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
    <%@include file="/common/common.jsp" %>
    <style type="text/css">
        h3{margin-bottom:10px;margin-top: 20px;}
        .tip{color:grey;font-style: italic;margin-left: 20px;}
    </style>
</head>
<body>
<div class="page">
    <div class="page-content">
        <h3>标准按钮</h3>
        <button class="ui-button ui-button-primary mr-2">按钮</button>
        <button class="ui-button ui-button-success mr-2">按钮</button>
        <button class="ui-button ui-button-warning mr-2">按钮</button>
        <button id="sendEmoji" class="ui-button ui-button-error mr-2">添加标签按钮</button>
    </div>

    <div id="editor"  placeholder="请输入您的内容" contenteditable="true"
         style="overflow-y:scroll;width: 500px;height: 300px;margin-left: 100px; line-height: 20px">

    </div>
</div>
<script type="text/javascript">

    var inputResizeDom;
    var edit = document.getElementById('editor')
    var sendEmoji = document.getElementById('sendEmoji')

    // 定义最后光标对象
    var lastEditRange;

    // 编辑框点击事件
    edit.onclick = function() {
        // 获取选定对象
        var selection = getSelection()
        // 设置最后光标对象
        lastEditRange = selection.getRangeAt(0)
    }

    // 编辑框按键弹起事件
    edit.onkeyup = function() {
        // 获取选定对象
        var selection = getSelection()
        // 设置最后光标对象
        lastEditRange = selection.getRangeAt(0)
    }

/* 此处代码可以屏蔽掉,这是每次插入后定位到末尾的代码
    editor.onfocus = function () {
        window.setTimeout(function () {
            var sel,range;
            if (window.getSelection && document.createRange) {
                range = document.createRange();
                range.selectNodeContents(editor);
                range.collapse(true);
                range.setEnd(editor, editor.childNodes.length);
                range.setStart(editor, editor.childNodes.length);
                sel = window.getSelection();
                sel.removeAllRanges();
                sel.addRange(range);
            } else if (document.body.createTextRange) {
                range = document.body.createTextRange();
                range.moveToElementText(editor);
                range.collapse(true);
                range.select();
            }
        }, 1);
    }
*/
    // 表情点击事件
    sendEmoji.onclick = function() {
        insertAtCursorDiv(edit,"添加标签按钮");
    }

    //插入标签
    function insertAtCursorDiv(myField, myValue) {
        // 编辑框设置焦点
        myField.focus()
        // 获取选定对象
        var selection = window.getSelection();//getSelection()
        // 判断是否有最后光标对象存在
        if (lastEditRange) {
            // 存在最后光标对象,选定对象清除所有光标并添加最后光标还原之前的状态
            selection.removeAllRanges()
            selection.addRange(lastEditRange)
        }

        var emojiText = document.createElement("input")
        emojiText.setAttribute("value", "标签的文字");
        emojiText.setAttribute("data-code", "123");
        emojiText.setAttribute("disabled", 'true');
        emojiText.style.width = input_resize("标签的文字") + 'px';
        emojiText.style.background = 'lightskyblue';
        emojiText.style.borderRadius = '10px';
        emojiText.style.textAlignLast = 'center';
        emojiText.style.font = '16px';

        insertHtmlAtCaret(emojiText.outerHTML);
        // 无论如何都要记录最后光标对象
        lastEditRange = selection.getRangeAt(0)
    }

    var modalVm = avalon.define({
        $id:'inputLabel',

    });

    componentDidMount();

    function componentDidMount(){
        //增加隐藏节点,编辑模板时计算标签宽度
        if($('.hidden').length < 1){
            inputResizeDom = document.createElement('span');
            inputResizeDom.setAttribute('class', 'hide-dom');
            document.getElementsByTagName('body')[0].appendChild(inputResizeDom);
        }
    }

    function input_resize(html) {
        inputResizeDom.innerHTML = html;
        inputResizeDom.style.fontSize = '16px';
        return inputResizeDom.getBoundingClientRect().width.toFixed(4);
    }


    function insertHtmlAtCaret(html) {

        var sel, range;

        if (window.getSelection) {

            sel = window.getSelection();

            if (sel.getRangeAt && sel.rangeCount) {

                range = sel.getRangeAt(0);

                range.deleteContents();

                var el = document.createElement("input");

                el.innerHTML = html;

                var frag = document.createDocumentFragment(), node, lastNode;

                while ( (node = el.firstChild) ) {

                    lastNode = frag.appendChild(node);

                }
                range.insertNode(frag);

                if (lastNode) {

                    range = range.cloneRange();

                    range.setStartAfter(lastNode);

                    range.collapse(true);

                    sel.removeAllRanges();

                    sel.addRange(range);

                }

            }

        } else if (document.selection && document.selection.type != "Control") {
            document.selection.createRange().pasteHTML(html);
        }
    }
</script>
</body>
</html>

这是一个比较全的代码,当然还是有参考文章的
js之向div contenteditable光标位置添加字符
js-处理div设置的编辑框处理焦点定位追加内容

上一篇下一篇

猜你喜欢

热点阅读