如果输入 Enter 键,可编辑 div 上的选择不起作用

问题描述 投票:0回答:2

我有一个可编辑的 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>

javascript jquery range selection
2个回答
0
投票

不需要额外的库。简单的 JS 解决方案在这里

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>


-1
投票

当您在

contenteditable
div 内按 Enter 时,浏览器会将新创建的行放入其自己的 div 内,从而创建新的文本节点。结果是
cp
可能不是
textNode
内的位置。

© www.soinside.com 2019 - 2024. All rights reserved.