Quill.js将自定义javascript函数添加到编辑器中

时间:2019-10-03 16:29:17

标签: javascript html quill

我正在使用Quill.js来让用户在主页上创建自定义的用户设计页面。我有一个用JavaScript编写的自定义滑块,它将拍摄图像并在图像中旋转。我在羽毛笔设置中有工具栏,能够单击工具栏以在模态窗口中设置滑块。

当用户单击以关闭模式滑块设置窗口时,我试图在光标所在的html编辑器中插入一个编辑按钮,以便用户可以编辑刚刚输入的信息,也可以通过以下方式删除该按钮:删除滑块模态窗口中的所有信息。

我写了自定义污点,跟随着所有我能找到的例子,但没有任何效果。我确实获得了要显示的自定义html标签,但没有按钮。当我在编辑器中设置自定义html标记时从羽毛笔请求html时,从quill.root.innerHTML中获得的只是“

”,自定义标记或其中的信息均不存在即使我在编辑器中正确看到它也是如此。

我希望编辑器中的一个按钮使编辑滑块数据变得容易,因为可能会有多个。我不会限制滑块的数量。用户可以自行破坏自己的页面。

我不会在编辑html窗口中呈现滑块,只是试图显示一个单击按钮。我确实向用户提供了模态窗口上的预览按钮,以便他们选择滑块。

我还想将滑块的设置信息以json格式存储在按钮中的数据标签中,并在浏览器窗口中呈现html时将该html按钮与json数据一起更改为标签。

这可以在Quill.js中完成吗?

1 个答案:

答案 0 :(得分:0)

我通过使用嵌入的导入印迹来完成此操作。我没有注册为按钮,但是单击污点时,我确实获得了指向嵌入数据的链接,并在该单击上触发了轮播数据的编辑。

var Quill;
const BlockEmbed = Quill.import("blots/block/embed");
const Link = Quill.import('formats/link');


class Carousel extends BlockEmbed {
    static create(value) {
        var self = this;
        const node = super.create(value);
        node.dataset.carousel = JSON.stringify(value);
        value.file.frames.forEach(frame => {
            const frameDiv = document.createElement("div");
            frameDiv.innerText = frame.title;
            frameDiv.className += "previewDiv";
            node.appendChild(frameDiv);
        });
        node.onclick = function () {
            if (Carousel.onClick) {
                Carousel.onClick(self, node);
            }
        };
        return node;
    }

    static value(domNode) {
        return JSON.parse(domNode.dataset.carousel);
    }

    static onClick: any;

    static blotName = "carousel";
    static className = "ql-carousel";
    static tagName = "DIV";
}

Quill.register("formats/carousel", Carousel);

然后我将其作为脚本添加到羽毛笔正在编辑HTML的页面上

<script src="~/js/quilljs-carousel.js"></script>

然后这是用于处理隐藏div标签中的自定义模式对话框中显示的污点事件的自定义javascript

<script>
    function CarouselClicked(blot, node) {
        editCarousel(JSON.parse(node.dataset.carousel), node);
    }

    var Carousel = Quill.import("formats/carousel");
    Carousel.onClick = CarouselClicked;

    function carouselToolbarClickHandler() {
        createCarousel();
    }

    var Toolbar = Quill.import("modules/toolbar");
    Toolbar.DEFAULTS.handlers.carousel = carouselToolbarClickHandler;

    $(document).ready(function() {
        var div = $("#editor-container");
        var Image = Quill.import('formats/image');
        Image.className = "img-fluid";
        Quill.register(Image, true);
        var quill = new Quill(div.get(0),
            {
                modules: {
                    syntax: true,
                    toolbar: '#toolbar-container'
                },
                theme: 'snow'
            });
        div.data('quill', quill);

        // Only show the toolbar when quill is ready to go
        $('#toolbar-container').css('display', 'block');
        div.css('display', 'block');
        $('#editor-loading').css('display', 'none');
        // Override the quill Image handler and create our own.
        quill.getModule("toolbar").addHandler("image", imageHandler);
    });

    function createCarousel() {
        $("#carouselModalForm").removeClass("was-validated").get(0).reset();
        $("#carouselModalList").empty();
        $("#carouselModal")
            .data("state", "unsaved")
            .one("hidden.bs.modal",
                function() {
                    var data = getCarouselData();
                    var carouselData = {};
                    carouselData['file'] = data;
                    carouselData['speed'] = $('#time').val();
                    carouselData['height'] = $('#height').val();
                    carouselData['width'] = $('#width').val();
                    var quill = $("#editor-container").data().quill;
                    var range = quill.getSelection(true);
                    if (range != null) {
                        quill.insertEmbed(
                            range.index,
                            "carousel",
                            carouselData,
                            Quill.sources.USER
                        );
                        quill.setSelection(range.index + 2, Quill.sources.USER);
                    }
                })
            .modal("show");
        $('#title').get(0).outerText = "Create Carousel";
    }

    function editCarousel(value, node) {
        $("#carouselModalForm").get(0).reset();
        var elem = $("#carouselModalList").empty();
        $.each(value.file.frames,
            function(i, data) {
                $("<option>").appendTo(elem).text(data.title).data("frame", data);
            });
        $('#time').val(value.speed);
        $('#height').val(value.height);
        $('#width').val(value.width);

        var modal = $("#carouselModal");

        modal.find("form").removeClass("was-validated");
        modal
            .data("state", "unsaved")
            .one("hidden.bs.modal",
                function() {
                    if ($("#carouselModal").data("state") !== "saved")
                        return;
                    var data = getCarouselData();
                    var carouselData = {};
                    carouselData['file'] = data;
                    carouselData['speed'] = $('#time').val();
                    carouselData['height'] = $('#height').val();
                    carouselData['width'] = $('#width').val();
                    var carousel = Quill.find(node, true);
                    carousel.replaceWith("carousel", carouselData);
                })
            .modal("show");
        $('#title').get(0).outerText = "Edit Carousel";
    }

    function getCarouselData() {
        var options = $("#carouselModalList").find("option");
        var frames = $.map(options,
            function(domNode) {
                return $(domNode).data("frame");
            });

        return {
            frames : frames
        };
    }

    function getCarouselFrameFormData() {
        // Get data from frame
        function objectifyForm(formArray) { //serialize data function
            var returnArray = {};
            for (var i = 0; i < formArray.length; i++) {
                returnArray[formArray[i]['name']] = formArray[i]['value'];
            }
            return returnArray;
        }

        return objectifyForm($("#carouselFrameModalForm").serializeArray());
    }

    $("#carouselModalNewFrame").click(function() {
        $("#carouselFrameModalForm").removeClass("was-validated").get(0).reset();
        $("#backgroundPreview").attr("src", "");
        $("#mainPreview").attr("src", "");
        $("#carouselFrameModal")
            .data("state", "unsaved")
            .one("hidden.bs.modal",
                function() {
                    if ($("#carouselFrameModal").data("state") == "saved") {
                        var data = getCarouselFrameFormData();
                        $("<option>").appendTo($("#carouselModalList")).text(data.title).data("frame", data);
                    }
                })
            .modal("show");
        // Fetch all the forms we want to apply custom Bootstrap validation styles to

    });

    $("#carouselModalEditFrame").click(function () {
        var form = $("#carouselFrameModalForm");
        form.removeClass("was-validated").get(0).reset();
        var selected = $("#carouselModalList option:selected");
        var frame = selected.data("frame");
        $.each(Object.keys(frame),
            function (i, e) {
                $("input[name=" + e + "]", form).val(frame[e]);
            });
        $("#backgroundPreview").attr("src", frame.backgroundImg);
        $("#mainPreview").attr("src", frame.mainImg);
        $("#carouselFrameModal")
            .data("state", "unsaved")
            .one("hidden.bs.modal",
                function() {
                    if ($("#carouselFrameModal").data("state") == "saved") {
                        var data = getCarouselFrameFormData();
                        selected.text(data.title).data("frame", data);
                    }
                })
            .modal("show");
    });

    $("#carouselModalRemoveFrame").click(function () {
        $("#confirm-delete").modal("show");
    });

    $("#carouselFrameModalForm").find("input:file").change(function() {
        var elem = $(this);
        var target = elem.data("target");
        var preview = elem.data("preview");
        FiletoBase64(this, preview, target);
    });

    $("#carouselModalList").change(function() {
        var selected = $("option:selected", this);
        $("#carouselModalEditFrame,#carouselModalRemoveFrame").prop("disabled", !selected.length);
    });
    $("#carouselModalSave").click(function() {
        // Validate frameset
        var form = $("#carouselModalForm").get(0);
        var select = $("#carouselModalList");
        if (select.find("option").length == 0) {
            select.get(0).setCustomValidity("Need at least one frame");
        } else {
            select.get(0).setCustomValidity("");
        }
        if (form.checkValidity()) {
            $("#carouselModal").data("state", "saved");
            $("#carouselModal").modal("hide");
        }
        else {
            $("#carouselModalForm").addClass("was-validated");
        }

    });
    $("#carouselFrameModalSave").click(function() {
        // Validate frame
        if ($("#carouselFrameModalForm").get(0).checkValidity()) {
            $("#carouselFrameModal").data("state", "saved");
            $("#carouselFrameModal").modal("hide");
        }
        else {
            $("#carouselFrameModalForm").addClass("was-validated");
        }
    });
    $('#confirm-delete-delete').click(function () {

        $("#carouselModalList option:selected").remove();
        $("#confirm-delete").modal("hide");


    });

    // #region Image FileExplorer Handler
    function insertImageToEditor(url) {
        var div = $("#editor-container");
        var quill = div.data('quill');
        var range = quill.getSelection();
        quill.insertEmbed(range.index, 'image', url);
    }

    function CarouselMainimageHandler() {
        $("#CarouselMainimageSelectFileExplorer").fileExplorer({
            directoryListUrl: '@Url.Action("DirectoryList", "FileTree")',
            fileListUrl: '@Url.Action("FileList", "FileTree")'
        });
        $("#CarouselMainimageSelectModal").modal("show");
    }

    $("#CarouselMainimageSelectModal").on("hide.bs.modal",
        function() {
            $("#CarouselMainimageSelectFileExplorer").fileExplorer("destroy");
        });
    $("#CarouselMainimageSelectSelectButton").click(function() {
        var id = $("#CarouselMainimageSelectFileExplorer").fileExplorer("getSelectedFileId");
        if (id == null) {
            alert("Please select a file");
            return;
        }
        var imageName = $("#CarouselMainimageSelectFileExplorer").fileExplorer("getSelectedFileName");
        var imageLink = "@Url.Action("Render", "FileTree")?id=" + id;
        $("#mainImageName").val(imageName);
        $("#mainImageLink").val(imageLink);
        $("#mainImage").attr("src",imageLink);
        $("#mainImage").show();
        $("#CarouselMainimageSelectModal").modal("hide");
    });


    function CarouselBackgroundimageHandler() {
        $("#CarouselBackgroundimageSelectFileExplorer").fileExplorer({
            directoryListUrl: '@Url.Action("DirectoryList", "FileTree")',
            fileListUrl: '@Url.Action("FileList", "FileTree")'
        });
        $("#CarouselBackgroundimageSelectModal").modal("show");
    }

    $("#CarouselBackgroundimageSelectModal").on("hide.bs.modal",
        function() {
            $("#CarouselBackgroundimageSelectFileExplorer").fileExplorer("destroy");
        });
    $("#CarouselBackgroundimageSelectSelectButton").click(function() {
        var id = $("#CarouselBackgroundimageSelectFileExplorer").fileExplorer("getSelectedFileId");
        if (id == null) {
            alert("Please select a file");
            return;
        }
        var imageName = $("#CarouselBackgroundimageSelectFileExplorer").fileExplorer("getSelectedFileName");
        var imageLink = "@Url.Action("Render", "FileTree")?id=" + id;
        $("#backgroundImageName").val(imageName);
        $("#backgroundImageLink").val(imageLink);
        $("#backgroundImage").attr("src",imageLink);
        $("#backgroundImage").show();
        $("#CarouselBackgroundimageSelectModal").modal("hide");
    });


    function imageHandler() {
        $("#imageSelectFileExplorer").fileExplorer({
            directoryListUrl: '@Url.Action("DirectoryList", "FileTree")',
            fileListUrl: '@Url.Action("FileList", "FileTree")'
        });
        $("#imageSelectModal").modal("show");
    }

    $("#imageSelectModal").on("hide.bs.modal",
        function() {
            $("#imageSelectFileExplorer").fileExplorer("destroy");
        });
    $("#imageSelectSelectButton").click(function() {
        var id = $("#imageSelectFileExplorer").fileExplorer("getSelectedFileId");
        if (id == null) {
            alert("Please select a file");
            return;
        }
        insertImageToEditor("@Url.Action("Render", "FileTree")?id=" + id);
        $("#imageSelectModal").modal("hide");
    });
    // #endregion

    function Save() {
        var div = $("#editor-container");
        var quill = div.data('quill');

        $('#alertSave').show();
        $.post({
            url: '@Url.Action("Save")',
            data: { BodyHtml: quill.root.innerHTML, locationId: @(Model.LocationId?.ToString() ?? "null") },
            headers: {
                '@Xsrf.HeaderName': '@Xsrf.RequestToken'
            }
        }).done(function() {
            $('#alertSave').hide();
            $('#alertSuccess').show();
            setTimeout(function() { $('#alertSuccess').hide(); }, 5000);
        }).fail(function(jqXhr, error) {
            var alert = $('#alertFailure');
            var text = $("#alertFailureText");
            text.text(error.ErrorMessage);
            alert.show();
        });
    }

    function FiletoBase64(input, imgName, Base64TextName) {
        var preview = document.getElementById(imgName);
        var file = input.files[0];
        var reader = new FileReader();
        reader.addEventListener("load",
            function() {
                preview.src = reader.result;
                document.getElementById(Base64TextName).value = reader.result;
            },
            false);
        if (file) {
            reader.readAsDataURL(file);
        }
    }
</script>