js富文本编辑器 简易版

编辑器功能很少,小项目需求。案例是vue组件,支持多个

tips:操作按钮必须用img标签

使用方法

<q-editor ref="editor" :content="content"></q-editor>

取值

this.$refs.editor.getContent()

源码

// 富文本编辑器
Vue.component('q-editor', {
    data() {
        return {
            operationList: [
                {title: '加粗', exec: 'bold'},
                {title: '斜体', exec: 'italic'},
                {title: '下划线', exec: 'underline'},
                {title: '删除线', exec: 'strikeThrough'},
                {title: '居左', exec: 'justifyLeft'},
                {title: '居中', exec: 'justifyCenter'},
                {title: '居右', exec: 'justifyRight'},
                {title: '图片', exec: 'insertImage'}
            ],
            fileInput: null
        }
    },
    props: {
        content: {
            type: String,
            default: '<p><br></p>'
        },
    },
    template: `
        <div class="q_editor">
            <div class="q_ed_operation">
                <template v-for="(d, index) in operationList" :key="index">
                    <a :key="index" @click="setExecCommand(d)">
                        <img :src="'/image/q-editor/'+d.exec+'.png'" alt="">
                    </a>
                  </template>
            </div>
            <div class="q_ed_content" ref="q_ed_content" contentEditable="true" @paste.prevent="stick" @keydown.enter.prevent="preventEnter($event)" v-html="content"></div>
        </div>
    `,
    mounted() {
        // 初始化文本内容
        if (this.content.length < 1) {
            this.$refs.q_ed_content.innerHTML = '<p><br></p>'
        }
        document.execCommand('styleWithCSS', false, true);
    },
    methods: {
        //屏蔽默认回车,插入换行符
        preventEnter() {
            document.execCommand('insertHTML', false, `<p><br></p>`)
        },
        // 粘贴板清空样式
        stick(e) {
            e.preventDefault();
            var text;
            var clp = (e.originalEvent || e).clipboardData;
            if (clp === undefined || clp === null) {
                text = window.clipboardData.getData("text") || "";
                if (text !== "") {
                    if (window.getSelection) {
                        var newNode = document.createElement("span");
                        newNode.innerHTML = text;
                        window.getSelection().getRangeAt(0).insertNode(newNode);
                    } else {
                        document.selection.createRange().pasteHTML(text);
                    }
                }
            } else {
                text = clp.getData('text/plain') || "";
                if (text !== "") {
                    document.execCommand('insertText', false, text);
                }
            }
        },
        // execCommand 设置基础样式
        setExecCommand(item) {
            const _this = this;
            // 光标移入编辑框
            this.$refs.q_ed_content.focus();
            if (item.exec === 'insertImage') {
                // 创建上传控件
                this.fileInput = document.createElement("input");
                this.fileInput.type = 'file';
                this.fileInput.name = 'name';
                this.fileInput.accept = 'image/gif,image/jpeg,image/jpg,image/png';
                this.fileInput.click();

                this.fileInput.onchange = function () {
                    var file = _this.fileInput.files[0];
                    var formData = new FormData();
                    formData.append("", file);
                    formData.append("img_type", 3);
                    var xhr = new XMLHttpRequest();
                    xhr.open("post", "/uploadImg");
                    xhr.send(formData);
                    xhr.onload = function () {
                        var xhrData = JSON.parse(xhr.response);
                        if (xhrData.error_code == 0) {
                                // 插入图片
                                document.execCommand('insertImage', false, xhrData.result);
                        } else {
                        		console.log('上传图片失败')
                        }
                        // 销毁上传控件
                        _this.fileInput = null
                    };
                }
            } else {
                this.execOperation(item.exec)
            }
        },
        //最终执行函数
        execOperation(name) {
            // 获取当前选区
            let selection = window.getSelection();
            let getRange = selection.getRangeAt(0);
            if (!getRange.toString()) {
                return false
            }
            let bool = document.execCommand(name);
            getRange.detach();
            return bool
        },
        //规划html标签
        getContent() {
            const ele = this.$refs.q_ed_content;
            let innerHTML = ele.innerHTML;

            // 图片垂直居中
            if (innerHTML.indexOf('<img src=') > -1) {
                innerHTML = innerHTML.replace(/<img src=/g, '<img style="vertical-align: middle;" src=');
            }

            return innerHTML

        }
    }
});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值