使用 Rangy 保存其位置时,插入符号在 Firefox 中消失

2023-11-27

这种情况仅发生在 Firefox 中。

重要提示:我正在保存插入符的位置rangy.saveSelection():

  • 当点击内容可编辑div时
  • on keyup
  • 将外部 html 元素(作为节点)添加到内容可编辑 div 时

我需要通过多种方式不断保存位置,以便能够在单击时插入 html 元素(我有一些标签)。

当我单击 contentEditable div 并且该 div 为空(比方说,第一个焦点)时,除非开始输入,否则我看不到插入符号。如果插入符号在末尾,我也看不到它。

另一个奇怪的行为是我无法使用箭头在 contentEditable div 中的文本之间导航。

如果我删除(不断)保存插入符号位置(在输入、单击等时)的功能,插入符号将恢复正常(插入符号可见)。

当我开始保存插入符的位置时出现问题。显然我应该做某种重置或清除..但根据我的理解,这些似乎适得其反(因为根据我的理解,它们破坏了保存的插入符位置)。

内容可编辑div

                <div class="input__boolean input__boolean--no-focus">
                    <div 
                            @keydown.enter.prevent
                            @blur="addPlaceholder"
                            @keyup="saveCursorLocation($event); fixDelete(); clearHtmlElem($event);"
                            @input="updateBooleanInput($event); clearHtmlElem($event);"
                            @paste="pasted"
                            v-on:click="clearPlaceholder(); saveCursorLocation($event);"
                            class="input__boolean-content"
                            ref="divInput"
                            contenteditable="true">Cuvinte cheie, cautare booleana..</div>
                </div>

我的方法/功能

            inputLength($event){
                this.input_length = $event.target.innerText.length;
                if(this.input_length == 0)
                    this.typed = false;
            },
            addPlaceholder(){
                if(this.input_length == 0 && this.typed == false){
                    this.$refs.divInput.innerHTML = 'Cuvinte cheie, cautare booleana..'
                }
            },
            clearPlaceholder(){
                if(this.input_length == 0 && this.typed == false){
                    this.$refs.divInput.innerHTML = '';
                }
            },
            updateBooleanInput($event){
                this.typed = true;
                this.inputLength($event);
            },
            saveCursorLocation($event){
                if($event.which != 8){
                    if(this.saved_sel)
                        rangy.removeMarkers(this.saved_sel)
                    this.saved_sel = rangy.saveSelection();
                }
                // if(this.input_length == 0 && this.typed == false){
                //  var div = this.$refs.divInput;
                //  var sel = rangy.getSelection();
                //  sel.collapse(div, 0);
                // }
            },
            insertNode: function(node){
                var selection = rangy.getSelection();
                var range = selection.getRangeAt(0);
                range.insertNode(node);
                range.setStartAfter(node);
                range.setEndAfter(node);
                selection.removeAllRanges();
                selection.addRange(range);
            },
            addBooleanTag($event){
                // return this.$refs.ChatInput.insertEmoji($event.img);
                this.$refs.divInput.focus();
                console.log(this.input_length);
                if(this.typed == false & this.input_length == 0){
                    this.$refs.divInput.innerHTML = ''
                    var space = '';
                    this.typed = true
                    this.saveCursorLocation($event);
                }
                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', (event) => {
                    // event.currentTarget.node.setAttribute('contenteditable','false');
                    this.$refs.divInput.removeChild(node);
                })
                this.insertNode(node);
                this.saveCursorLocation($event);
            },
            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;
                            }
                        }
                    }
                }
            },
            pasted($event){
                $event.preventDefault();
                var text = $event.clipboardData.getData('text/plain');
                this.insert(document.createTextNode(text));
                this.inputLength($event);
                this.typed == true;
            },
            insert(node){
                this.$refs.divInput.focus();
                this.insertNode(node);
                this.saveCursorLocation($event);
            },

正如您在 saveCursorLocation() 中看到的,我试图解决您单击 contentEditable div 并且没有插入符号的情况 - 这会让用户感到困惑。

                // if(this.input_length == 0 && this.typed == false){
                //  var div = this.$refs.divInput;
                //  var sel = rangy.getSelection();
                //  sel.collapse(div, 0);
                // }

这是一个死胡同 - 很可能是因为我对 Rangy 以及我应该如何使用这些功能了解甚少。

Firefox 上的预期行为与实际结果

当我单击 contentEditable div 时,我希望出现插入符号(同时在后台保存我的位置)。打字时,我希望插入符号出现在最后输入的字符之后,同时在键盘上保存插入符号的位置。此外,我希望能够通过左/右箭头导航文本,并在执行此操作时看到插入符号。

所有这些都是由

v-on:click="..... saveCursorLocation($event);"

and

@keyup="saveCursorLocation($event);....."

如果有人认为这会有帮助,我可以在 Firefox 中记录内容可编辑 div 及其行为。

编辑:我设法隔离问题并将其重现到 JSFiddle -https://jsfiddle.net/Darkkz/6Landbj5/13.

要找什么?

  • 在 Firefox 中打开小提琴链接,然后按蓝色按钮之一(SI、SAU、NU),然后查看输入,插入符号未显示。
  • 点击输入,插入符号不显示
  • 输入时,不显示插入符号。不过,如果您单击单词/内容之间的内容,则会显示插入符号

显然是兰吉的选择保存和恢复模块当用户与某个对象交互时,不能用于跟踪当前选择contenteditable, 像你要的那样。

我深入研究了一下,问题是远程插入隐藏了<span>s 作为标记,并且将选择更新为标记之后,而不是将其保留在#text用户编辑的节点:

 <div contenteditable>
    #text [This is something I typed <!-- selection is moved from here -->] 
    <span class="rangySelectionBoundary"/>
    <!-- to here -->
 </div>

Firefox 在这种情况下无法显示插入符号(我还没有发现有关此特定问题的错误,但这里有一个类似的错误,其中当选择在两个之间时,不显示插入符号<span>s).

注释掉这段代码似乎可以解决插入符号消失的问题。我不清楚为什么需要该代码 - 它1.0之前添加在一个大型提交中,其消息如下:“修复了控制范围和多个范围选择的保存/恢复问题。添加了保存/恢复和 CSS 类应用程序模块的演示。”——所以我不太愿意建议在 rangy 中修复这个问题(而且由于它已经有几年没有维护了,所以我对得到其作者的意见没有太大希望)。

所以我试图弄清楚为什么你首先需要这个,以建议其他不涉及的解决方案rangy.saveSelection(例如,兰吉的文本范围模块提供getSelection().saveCharacterRanges(containerNode)无需修改 DOM 即可工作。

看来您有一个<div contenteditable>和一些“按钮”(<span>s),单击它将在插入符号位置插入一些 HTML。您试图解决的问题是,当单击“按钮”时,选择从contenteditable插入按钮,并且您无法检测插入位置。

您可以制作按钮,而不是存储和恢复选择user-select: none- 这将使内容中的插入符号保持可编辑。

为了测试这一点,我注释掉了所有引用rangy.saveSelection and rangy.restoreSelection并改变了this.$refs.divInput.focus();调用“按钮”onclick处理程序仅在以下情况下运行contenteditable还没有通过将其包裹在一个集中if (!this.$refs.divInput.contains(document.activeElement))。在这个更新的小提琴中看看它是如何工作的:
https://jsfiddle.net/fjxsgvm2/

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Rangy 保存其位置时,插入符号在 Firefox 中消失 的相关文章

  • Twitter 卡元标签问题

    有问题的网址 https www halleonard com viewpressreleasedetail action releaseid 10261 https www halleonard com viewpressreleased
  • 如何针对 Node.js 中发生的每个错误发送电子邮件?

    假设我的 node js 应用程序正在运行 如果出现错误 我的意思是所有错误 不仅仅是网络错误 如果出现错误 则很重要 我如何调用函数向我发送电子邮件 基本上 在我希望它写入 err out 之前 我希望向我发送一封电子邮件 我正在使用no
  • 可以在初始 DOM 解析期间/之前修改 DOM 吗?

    是否可以在初始 DOM 解析期间或之前修改 DOM 或者我是否必须等到 DOM 被解析和构建之后才能与其交互 更具体地说 是否有可能阻止 DOM 中的脚本元素使用用户脚本 内容脚本或 Chrome 或 Firefox 中的类似脚本运行 在解
  • React-Redux:state.setIn() 和 state.set() 有什么区别?

    我见过使用setIn and set 在一些react redux代码中 state setIn state set 我在这里找到了一些文档https facebook github io immutable js https facebo
  • 如何纠正流警告:解构(缺少注释)

    我正在编写一个小型 React Native 应用程序 并且正在尝试使用 Flow 但我无法在任何地方真正获得有关它的正确教程 我不断收到错误 destructuring Missing annotation 有关 station 这段代码
  • Jquery 数据表列总和

    我只是参考一下这个链接 https datatables net examples advanced init footer callback html了解如何获取 jquery 数据表中的列总计 但我已经完成了一半的项目 我在html页面
  • php - 解析html页面

    div divbox div p para1 p p para2 p p para3 p table class table tr td td tr table p para4 p p para5 p 有人可以告诉我如何解析这个 html
  • 网站的主体和元素固定在 980px 宽度上,不会缩小

    我试图在 Rails 应用程序顶部启动前端 仅 HTML CSS 页面 但在使用 320px 视口时遇到问题 有些元素不会按比例缩小 我不明白为什么 我已经完成了检查元素 为各种元素提供了max width 100 and or width
  • window.location 和 location.href 之间的区别

    我对之间的区别感到困惑window location and location href 两者似乎都以相同的方式行事 有什么不同 window location是一个对象 它保存有关当前文档位置的所有信息 主机 href 端口 协议等 lo
  • 刷新页面时保存用户的选择

    我目前有一个页面显示不同团队的数据 我有一些数据 用户可以单击使其处于 打开 或 关闭 状态 并为每个数据显示不同的图标 它基本上就像一个清单 只是没有物理复选框 我想记住哪些 复选框 已被选中 即使在用户刷新页面或关闭浏览器并稍后返回之后
  • 为什么我们在打字稿中使用 HTMLInputElement ?

    我们为什么使用 document getElementById ipv as HTMLInputElement value 代替 document getElementById ipv value 功能getElementById返回具有类
  • 不可勾选的单选按钮与专有的复选框

    从 UI 角度来看 是拥有一组具有取消选中功能的单选按钮更好 还是拥有一组独占的复选框 意味着一次只能选中一个 更好 Update 我没想到对此会有如此负面的反应 如果我给出一个更接近其使用方式的示例 也许会有所帮助 我有一个充满数据绑定内
  • 日期出现奇怪的错误,“未捕获非法访问”

    所以我试图找到最新的DateJavascript 可以处理 我把它减少到 9 月 275760 并增加了我开始捕获未捕获的天数illegal access例外new Date 09 24 275760 to new Date 10 13 2
  • Three.js 各种大小的粒子

    我是 Three js 的新手 正在尝试找出添加 1000 个粒子的最佳方法 每个粒子都有不同的大小和颜色 每个粒子的纹理是通过绘制画布创建的 通过使用粒子系统 所有粒子都具有相同的颜色和大小 为每个粒子创建一个粒子系统是非常低效的 有没有
  • 代码镜像错误:未捕获错误:扩展集中无法识别扩展值([对象对象])

    全部 我目前正在从事一个React Electron项目 该项目的目标是完成一个Markdown编辑器 当我配置codemirror 该程序报告错误说 Uncaught Error Unrecognized extension value
  • 对于只触及我的工作表的 Google 表格脚本,收到“此应用程序未经验证”

    我正在编写一个 Google Sheets 脚本 我只想访问与 gs 文件关联的同一电子表格中的数据 似乎我应该有权在自己的电子表格中运行脚本 但是每当我运行一个函数时 我都会得到一个This app isn t verified信息 我该
  • 带参数的事件监听器

    我想将参数传递给 JavaScript 中的事件侦听器 我已经找到了解决方案 但我无法理解它们为什么或如何工作以及为什么其他解决方案不起作用 我有 C C 背景 但是 Javascript 函数的执行有很大不同 您能否帮助我理解以下示例如何
  • 从 FileReader 设置背景图像样式

    我正在寻找一种解决方案 允许我从文件上传输入中获取文件并通过设置 document body style backgroundImage 来预览它 以下代码用于在 Image 元素中显示预览 function setImage id tar
  • 如何在执行新操作时取消先前操作的执行?

    我有一个动作创建器 它会进行昂贵的计算 并在每次用户输入内容时调度一个动作 基本上是实时更新 但是 如果用户输入多个内容 我不希望之前昂贵的计算完全运行 理想情况下 我希望能够取消执行先前的计算并只执行当前的计算 没有内置功能可以取消Pro
  • Vue.js[vuex] 如何从突变中调度?

    我有一个要应用于 json 对象的过滤器列表 我的突变看起来像这样 const mutations setStars state payload state stars payload this dispatch filter setRev

随机推荐