提问人:provance 提问时间:10/27/2023 更新时间:10/28/2023 访问量:86
如果键入了 Enter,则在可编辑的 div 上进行选择不起作用
selection on editable div doesn't work if an Enter is typed
问:
我有一个可编辑的 div 和开始和结束标记之间的多个文本块
假设光标位于标记
之间的任何位置 单击按钮 我需要选择整个当前块three backticks
three backticks
这段代码一直有效,直到我在当前块
内的任何地方键入 - 我相信代码有一个较短的版本Enter
function get_left(){
let s = window.getSelection();
let range = s.getRangeAt(0);
let so = range.startOffset;
let textNode = range.startContainer;
let textContent = textNode.textContent;
let startPosition = Math.max(so - 4, 0);
let a = textContent.substring(startPosition, so);
return a;
}
function go_left(){
let par = document.getElementById("cstory");
let s = window.getSelection();
let range = document.createRange();
let cp = window.getSelection().getRangeAt(0).startOffset;
let textNode = par.firstChild;
range.setStart(textNode, cp - 1);
range.setEnd(textNode, cp - 1);
s.removeAllRanges();
s.addRange(range);
}
$('button').on('click', async function(){
while(get_left() !== "```\n"){go_left();}
let s = window.getSelection();
let range = s.getRangeAt(0);
let story = document.getElementById("cstory").innerText;
let nextXIndex = story.indexOf("\n```", range.endOffset);
if(nextXIndex !== -1){
range.setEnd(range.endContainer, nextXIndex);
s.removeAllRanges();
s.addRange(range);
}
});
.cstory{white-space:pre-wrap;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='cstory' id='cstory' contenteditable>
lorem sea
```
lorem ipsum
dolor sit
sky
```
lorem sky
```
lorem ipsum
dolor sit
sky
```
dolor sit
</div>
<br>
<button>CLICK</button>
答:
-1赞
Raf Vosté
10/27/2023
#1
当您在 div 中按回车键时,浏览器会将新创建的行放入它们自己的 div 中,从而创建新的文本节点。结果是可能不是 中的位置。contenteditable
cp
textNode
评论
0赞
provance
10/27/2023
它不应该是因为cstory
-webkit-user-modify: read-write-plaintext-only;
0赞
Afzal K.
10/27/2023
@provance不再适用于新浏览器
0赞
provance
10/27/2023
@AfzalK。- ???- 我使用的是 Chrome,最新版本
0赞
DarkBee
10/27/2023
这如何回答这个问题?
0赞
Afzal K.
10/27/2023
@provance添加了双引号,因此它将不再起作用
1赞
Afzal K.
10/28/2023
#2
不需要其他库。这里的普通 JS 解决方案,防止创建 div 并替换双引号,以便它可以顺利工作,因为要求是选择反引号之间的文本,双引号会破坏格式并且选择不起作用
document.querySelector('div[contenteditable]').addEventListener('keydown', function(e) {
// creating a new selection element
let sltcn = window.getSelection()
// identifying the current position of the cursor within the text
let range = sltcn.getRangeAt(0)
// saveing the current cursor position in a variable
let position = range.startOffset
if (event.key === 'Enter') {
document.execCommand('insertLineBreak');
// getting the content of the inner HTML of the 'cstory' element and removing any quotation marks
let content = document.getElementById("cstory").innerHTML;
content = content.replace(/"/g, "");
// updating the content without quotation marks
document.getElementById("cstory").innerHTML = content;
// checking if the cursor is at the end of the text
if (position === range.endOffset) {
// creating a new range at the start of the next paragraph
let newRange = document.createRange();
newRange.setStart(document.getElementById("cstory").childNodes[0], position + 1);
newRange.collapse(true);
sltcn.removeAllRanges();
sltcn.addRange(newRange);
} else {
// cursor is in the middle of the line, moving it to the end
range.setStart(document.getElementById("cstory").childNodes[0], position + 1);
sltcn.removeAllRanges();
sltcn.addRange(range);
}
event.preventDefault()
}
});
function clsl() {
// getting the 'cstory' element
let cstory = document.getElementById("cstory");
// Getting the cursor position within the div
let crpos = window.getSelection().getRangeAt(0).startOffset;
// getting the text content
let cont = cstory.textContent;
// getting the position of the last 3 backticks
let firstticks = cont.lastIndexOf("```", crpos-1);
// getting the position of the first 3 backticks
let lastticks = cont.indexOf("```", crpos);
// If both starting and ending backticks are found, selecting the text between them
if (firstticks !== -1 && lastticks !== -1){
// Setting the selection range to start after the first backtick and end before the last backtick
let sltcn = window.getSelection();
let range = document.createRange();
// Setting the start and end of the range to include the text between the backticks
range.setStart(cstory.childNodes[0], firstticks+4);
range.setEnd(cstory.childNodes[0], lastticks);
sltcn.removeAllRanges();
sltcn.addRange(range);
}
}
.cstory{white-space:pre-wrap;}
<div class='cstory' id='cstory' contenteditable>
lorem sea
```
lorem ipsum
dolor sit
sky
```
lorem sky
```
lorem ipsum
dolor sit
sky
```
dolor sit
</div>
<br>
<button onclick="clsl()">CLICK</button>
评论
0赞
provance
10/28/2023
你是一个真正的英雄。多谢。顺便说一句,我认为这段代码对 javascript 来说是一个很大的耻辱。应该是-,不是吗?select_from prev_to_next(marker)
1赞
Afzal K.
10/28/2023
@provance没有经过我的脑海,有时间会试一试
评论