如果所述元素是第一个子元素,则无法删除 contentEditable 父元素中的 HTML 元素

Cannot delete HTML element in contentEditable parent if said element is the first child

问题

我正在构建一个自定义布尔搜索输入,它应该接受一些 "boolean tag bubbles" 形式的布尔标记,可以通过单击将其添加到查询中。基本上,用户可以点击 "AND" 布尔标记,而不是键入 {AND},并将其添加到输入中。请参阅所附图片以了解布局 - https://i.imgur.com/Fwa00zA.png

LE:此行为似乎只发生在 Chrome。

关于问题:如果首先在输入中添加标签,(如布局示例图片中所示)并且在添加标签之后类型字符仅到标签前的 return 并按退格键,则标签不会被删除。

只有当用户删除所有添加的字符时,才能通过退格键删除标签 - 基本上是在末尾移动插入符号,然后通过退格键删除所有内容。

我已经尝试过的

最初,我在问题和所有跨度之间建立了联系,这些跨度是在我使用 "left/right" 字符之间的方向键向布尔标记移动时生成的。因此我写了一些代码,每次我按下一个键,我都会扫描 contentEditable parent 并清除所有创建的 span 和 brs。这清除了一些奇怪的情况,但我仍然无法删除标签,如果它是第一个元素并且布尔标签之后有字符或其他元素。

几个小时前我发现了这个 - contenteditable div backspace and deleting text node problems。 插入我的布尔标记的函数将标记创建为元素。我尝试按照 post 中的建议将节点元素创建为 a。即使作为按钮,如果我的元素是第一个元素,后面有字符,也不能删除。

我的一些代码

对于我当前使用布尔标记作为元素的版本,这是在单击时创建我的布尔标记并将它们添加到父元素的方法。

            addBooleanTag($event){
                this.$refs.divInput.focus();
                if(this.typed == false & this.input_length == 0){
                    this.$refs.divInput.innerHTML = ''
                    var space = '';
                    this.typed = true
                    this.saveCursorLocation();
                }
                rangy.restoreSelection(this.saved_sel);

                var node = document.createElement('img');
                node.src = $event.img;
                node.className = "boolean-button--img boolean-button--no-margin";
                node.addEventListener('click', () => {
                    this.$refs.divInput.removeChild(node);
                })
                this.insertNode(node);
                this.saveCursorLocation();
            },

这是 contentEditable 父元素的样子

                <div 
                        @keydown.enter.prevent
                        @blur="addPlaceholder"
                        @keyup="saveCursorLocation(); clearHtmlElem($event)"
                        @input="updateBooleanInput($event); clearHtmlElem($event)"
                        @paste="pasted"
                        v-on:click="clearPlaceholder(); saveCursorLocation(); deleteBooleanTag();"
                        class="input__boolean input__boolean--no-focus"
                        ref="divInput"
                        contenteditable="true">Boolean search..</div>

这是清除中断和跨度的 contentEditable 父项的方法

            clearHtmlElem($event){
                var i = 0;
                var temp = $event.target.querySelectorAll("span, br");
                if(temp.length > 0){
                    for(i = 0; i < temp.length; i++){
                        if(!temp[i].classList.contains('rangySelectionBoundary')){
                            if (temp[i].tagName == "br"){
                                temp[i].parentNode.removeChild(temp[i]);
                            } else {
                                temp[i].outerHTML = temp[i].innerHTML;
                            }
                        }
                    }
                }
            },

预期行为与实际结果

我希望当我在插入符号位于布尔标记(img 元素)之后按退格键时删除该元素。一个正常的行为。 相反,它什么都不做。删除添加的 element/boolean 标签的唯一方法是如果标签是最后要删除的东西。

请看我在重现问题时制作的这张 gif。 https://imgur.com/a/vAXop2s - 当控制台 "freaks out" 时,基本上是我对那个 img element/boolean 标签和拒绝删除的元素按下退格键。

在一些帮助下,我设法解决了这个问题。我将此发布在这里,供遇到 contentEditable 问题的任何人使用。

不要设置 contentEditable 元素的样式。我在 contentEditable div 上有一些样式,这会弄乱很多东西,例如插入符号定位、退格键无法正常工作等。环绕它并在该包装器上移动样式。

LE:contentEditable 元素行为异常的一个(可能也是主要原因)原因是附加了 display:flex。