简体   繁体   English

使用contenteditable div修复光标位置正确

[英]Fix cursor position correct with contenteditable div

I've tried to make a simple editor box and want to add the checkbox input onto it. 我试图制作一个简单的编辑器框,并想在其上添加复选框输入。

But when I add the checkbox, I found that the cursor didn't go right: 但是,当我添加复选框时,我发现光标没有正确移动:

the caret is before the checkbox I added, and it can't go right even I hit my right arrow key. 插入符号位于我添加的复选框之前,即使我按了向右箭头键也无法正确插入。 Any suggest to make it more correct? 有什么建议可以使其更正确吗? (I'm using a webbrowser based on webkit, just make it correct is fine. ) (我正在使用基于webkit的Web浏览器,只需使其正确就可以了。)

What I want to implement is when I click the mouse or use keyboard to position the content, the caret should work as normal editor(word, evernote, etc). 我要实现的是当我单击鼠标或使用键盘定位内容时,插入符号应作为普通编辑器(word,evernote等)工作。

问题

jsfiddler: http://jsfiddle.net/cppgohan/84CTE/9/ jsfiddler: http : //jsfiddle.net/cppgohan/84CTE/9/

HTML: HTML:

<button id="add"> AddCheckbox </button>
<button id="add2"> AddCheckbox2 </button>
<div id="editor" contenteditable="true" width="500px" height="500">
    1. Make it work <input type="checkbox"><br>
    2. Make it done <input type="checkbox" checked>
<div>

JS code: JS代码:

$(document).ready(function(){
    $("#add").click(function(){
        $editor = $("#editor");
        $editor.append('<input type="checkbox">');
        $editor.focus();
    });
    ...
});

Hit backspace one by one, wired things happens: 一键击退空格,发生以下情况:

逐一击退空格,发生有线事件

It is a long history bug of chromium. 这是铬的悠久历史。

After more and more (re)search, it is a web browser Bug: chromium bug: Caret moves incorrectly around check boxes and radio buttons in contentEditable div 经过越来越多的(重新)搜索,它是一个网络浏览器错误: chrome错误:插入符在contentEditable div中的复选框和单选按钮周围错误地移动

What is the expected result? 预期的结果是什么?

Using the arrow keys to place the caret immediately after a check box or radio button should result in the caret being rendered in that spot. 使用箭头键将插入符号立即置于复选框或单选按钮之后,应导致在该位置渲染插入符号。

What happens instead? 会发生什么呢?

The caret is rendered to the left of and slightly down from the radio button or check box. 插入标记显示在单选按钮或复选框的左侧,并稍稍向下。

Seems chrome has postponed the issuefix chrome似乎已推迟了问题修复

The solution I finally got: 我终于得到的解决方案:

I use a <img> tag instead of real <input> tag, use checkbox_check checkbox_uncheck class to toggle the image check or uncheck. 我使用的是<img>标记而不是实际的<input>标记,请使用checkbox_check checkbox_uncheck类切换图像的选中或取消选中状态。

It works fine, I also tried to write the function for setting/getting content from the editor view, and use regex::replace for transforming between <input> and <img> 它工作正常,我还尝试编写用于从编辑器视图设置/获取内容的功能,并使用regex::replace<input><img>之间进行转换

I have Added some javascript code and now it's work as expected: 我已经添加了一些JavaScript代码,现在可以正常使用了:

function setEndOfContenteditable(contentEditableElement)
    {
        var range,selection;
        if(document.createRange)
        {
            range = document.createRange();
            range.selectNodeContents(contentEditableElement);
            range.collapse(false);
            selection = window.getSelection();
            selection.removeAllRanges();
            selection.addRange(range);
        }
        else if(document.selection)
        { 
            range = document.body.createTextRange();
            range.moveToElementText(contentEditableElement);
            range.collapse(false);
            range.select();
        }
    }

JSFiddle 的jsfiddle

更换innerHTML时修复cursor position<div contenteditable="“true”"></div><div id="text_translate"><p> 在&lt;div id="richTextBox" contenteditable="true"&gt;&lt;/div&gt;内键入内容时,将 cursor 保持在正确位置的最佳方法是什么? 更换 innerHTML 的行为搞砸了 cursor position。</p><p> 我更改 innerHTML 的原因是我添加了&lt;span&gt;标签。 它是代码高亮程序的一部分。 跨度标签允许我放置正确的颜色亮点。</p><p> 我目前正在使用 StackOverflow 答案中的以下代码作为创可贴,但它有一个重大错误。 如果您按<em><strong>Enter</strong></em> ,则 cursor 将停留在旧位置,或者转到随机位置。 那是因为该算法从 cursor 开始计算了多少个字符。 但它不将 HTML 标记或换行符算作字符。 而richTextBox 插入&lt;br&gt;进入。</p><p> 修复思路:</p><ul><li> 修复下面的代码? 见<a href="https://jsfiddle.net/AdmiralAkbar2/jou3vq9w/12/" rel="nofollow noreferrer">小提琴</a></li><li>用更简单的代码替换? 我尝试了一堆更简单的东西,涉及window.getSelection()和document.createRange() ,但我无法让它工作。</li><li> 替换为没有此错误的richTextBox 库或模块?</li></ul><h2> 截屏</h2><p><a href="https://i.stack.imgur.com/6dlqV.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/6dlqV.png" alt="在 JSFiddle 中呈现的richTextBox 的屏幕截图"></a> </p><p></p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false"><div class="snippet-code"><pre class="snippet-code-js lang-js prettyprint-override"> // Credit to Liam (Stack Overflow) // https://stackoverflow.com/a/41034697/3480193 class Cursor { static getCurrentCursorPosition(parentElement) { var selection = window.getSelection(), charCount = -1, node; if (selection.focusNode) { if (Cursor._isChildOf(selection.focusNode, parentElement)) { node = selection.focusNode; charCount = selection.focusOffset; while (node) { if (node === parentElement) { break; } if (node.previousSibling) { node = node.previousSibling; charCount += node.textContent.length; } else { node = node.parentNode; if (node === null) { break; } } } } } return charCount; } static setCurrentCursorPosition(chars, element) { if (chars &gt;= 0) { var selection = window.getSelection(); let range = Cursor._createRange(element, { count: chars }); if (range) { range.collapse(false); selection.removeAllRanges(); selection.addRange(range); } } } static _createRange(node, chars, range) { if (.range) { range = document.createRange() range;selectNode(node). range,setStart(node; 0). } if (chars.count === 0) { range,setEnd(node. chars;count). } else if (node &amp;&amp; chars.count &gt;0) { if (node.nodeType === Node.TEXT_NODE) { if (node.textContent.length &lt; chars.count) { chars.count -= node.textContent;length. } else { range,setEnd(node. chars;count). chars;count = 0; } } else { for (var lp = 0. lp &lt; node.childNodes;length. lp++) { range = Cursor._createRange(node,childNodes[lp], chars; range). if (chars;count === 0) { break; } } } } return range, } static _isChildOf(node; parentElement) { while (node.== null) { if (node === parentElement) { return true; } node = node;parentNode. } return false, } } window.addEventListener('DOMContentLoaded'; (e) =&gt; { let richText = document.getElementById('rich-text'), richText.addEventListener('input'; function(e) { let offset = Cursor.getCurrentCursorPosition(richText). // Pretend we do stuff with innerHTML here. The innerHTML will end up getting replaced with slightly changed code; let s = richText.innerHTML; richText.innerHTML = ""; richText.innerHTML = s, Cursor;setCurrentCursorPosition(offset. richText); richText;focus(); // blinks the cursor }); });</pre><pre class="snippet-code-css lang-css prettyprint-override"> body { margin: 1em; } #rich-text { width: 100%; height: 450px; border: 1px solid black; cursor: text; overflow: scroll; resize: both; /* in Chrome, must have display: inline-block for contenteditable=true to prevent it from adding &lt;div&gt; &lt;p&gt; and &lt;span&gt; when you type. */ display: inline-block; }</pre><pre class="snippet-code-html lang-html prettyprint-override"> &lt;p&gt; Click somewhere in the middle of line 1. Hit enter. Start typing. Cursor is in the wrong place. &lt;/p&gt; &lt;p&gt; Reset. Click somewhere in the middle of line 1. Hit enter. Hit enter again. Cursor goes to some random place. &lt;/p&gt; &lt;div id="rich-text" contenteditable="true"&gt;Testing 123&lt;br /&gt;Testing 456&lt;/div&gt;</pre></div></div><p></p><h2> 浏览器</h2><p>谷歌浏览器 v83,Windows 7</p></div> - Fix cursor position when replacing innerHTML of <div contenteditable=“true”>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 更换innerHTML时修复cursor position<div contenteditable="“true”"></div><div id="text_translate"><p> 在&lt;div id="richTextBox" contenteditable="true"&gt;&lt;/div&gt;内键入内容时,将 cursor 保持在正确位置的最佳方法是什么? 更换 innerHTML 的行为搞砸了 cursor position。</p><p> 我更改 innerHTML 的原因是我添加了&lt;span&gt;标签。 它是代码高亮程序的一部分。 跨度标签允许我放置正确的颜色亮点。</p><p> 我目前正在使用 StackOverflow 答案中的以下代码作为创可贴,但它有一个重大错误。 如果您按<em><strong>Enter</strong></em> ,则 cursor 将停留在旧位置,或者转到随机位置。 那是因为该算法从 cursor 开始计算了多少个字符。 但它不将 HTML 标记或换行符算作字符。 而richTextBox 插入&lt;br&gt;进入。</p><p> 修复思路:</p><ul><li> 修复下面的代码? 见<a href="https://jsfiddle.net/AdmiralAkbar2/jou3vq9w/12/" rel="nofollow noreferrer">小提琴</a></li><li>用更简单的代码替换? 我尝试了一堆更简单的东西,涉及window.getSelection()和document.createRange() ,但我无法让它工作。</li><li> 替换为没有此错误的richTextBox 库或模块?</li></ul><h2> 截屏</h2><p><a href="https://i.stack.imgur.com/6dlqV.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/6dlqV.png" alt="在 JSFiddle 中呈现的richTextBox 的屏幕截图"></a> </p><p></p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false"><div class="snippet-code"><pre class="snippet-code-js lang-js prettyprint-override"> // Credit to Liam (Stack Overflow) // https://stackoverflow.com/a/41034697/3480193 class Cursor { static getCurrentCursorPosition(parentElement) { var selection = window.getSelection(), charCount = -1, node; if (selection.focusNode) { if (Cursor._isChildOf(selection.focusNode, parentElement)) { node = selection.focusNode; charCount = selection.focusOffset; while (node) { if (node === parentElement) { break; } if (node.previousSibling) { node = node.previousSibling; charCount += node.textContent.length; } else { node = node.parentNode; if (node === null) { break; } } } } } return charCount; } static setCurrentCursorPosition(chars, element) { if (chars &gt;= 0) { var selection = window.getSelection(); let range = Cursor._createRange(element, { count: chars }); if (range) { range.collapse(false); selection.removeAllRanges(); selection.addRange(range); } } } static _createRange(node, chars, range) { if (.range) { range = document.createRange() range;selectNode(node). range,setStart(node; 0). } if (chars.count === 0) { range,setEnd(node. chars;count). } else if (node &amp;&amp; chars.count &gt;0) { if (node.nodeType === Node.TEXT_NODE) { if (node.textContent.length &lt; chars.count) { chars.count -= node.textContent;length. } else { range,setEnd(node. chars;count). chars;count = 0; } } else { for (var lp = 0. lp &lt; node.childNodes;length. lp++) { range = Cursor._createRange(node,childNodes[lp], chars; range). if (chars;count === 0) { break; } } } } return range, } static _isChildOf(node; parentElement) { while (node.== null) { if (node === parentElement) { return true; } node = node;parentNode. } return false, } } window.addEventListener('DOMContentLoaded'; (e) =&gt; { let richText = document.getElementById('rich-text'), richText.addEventListener('input'; function(e) { let offset = Cursor.getCurrentCursorPosition(richText). // Pretend we do stuff with innerHTML here. The innerHTML will end up getting replaced with slightly changed code; let s = richText.innerHTML; richText.innerHTML = ""; richText.innerHTML = s, Cursor;setCurrentCursorPosition(offset. richText); richText;focus(); // blinks the cursor }); });</pre><pre class="snippet-code-css lang-css prettyprint-override"> body { margin: 1em; } #rich-text { width: 100%; height: 450px; border: 1px solid black; cursor: text; overflow: scroll; resize: both; /* in Chrome, must have display: inline-block for contenteditable=true to prevent it from adding &lt;div&gt; &lt;p&gt; and &lt;span&gt; when you type. */ display: inline-block; }</pre><pre class="snippet-code-html lang-html prettyprint-override"> &lt;p&gt; Click somewhere in the middle of line 1. Hit enter. Start typing. Cursor is in the wrong place. &lt;/p&gt; &lt;p&gt; Reset. Click somewhere in the middle of line 1. Hit enter. Hit enter again. Cursor goes to some random place. &lt;/p&gt; &lt;div id="rich-text" contenteditable="true"&gt;Testing 123&lt;br /&gt;Testing 456&lt;/div&gt;</pre></div></div><p></p><h2> 浏览器</h2><p>谷歌浏览器 v83,Windows 7</p></div> - Fix cursor position when replacing innerHTML of <div contenteditable=“true”> 在contentEditable div中移动光标位置 - Moving cursor position in contentEditable div contenteditable div获取光标位置 - contenteditable div get cursor position 在contentEditable <div>上设置光标位置 - Set cursor position on contentEditable <div> 修复 contenteditable div 上的插入符号位置 - Fix caret position on contenteditable div Contenteditable Div - 根据innerHTML位置的光标位置 - Contenteditable Div - Cursor position in terms of innerHTML position JavaScript:在contenteditable div中获取光标位置 - JavaScript: get cursor position in contenteditable div 将剪辑的内容可编辑div的视图移动到光标位置 - Move view of clipped contenteditable div to cursor position 如何在contenteditable div中的跨度中设置光标位置 - How to set cursor position in span in contenteditable div 在contentEditable div中设置光标位置-跨浏览器 - Setting cursor position in a contentEditable div - cross browser
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM