获取选择所在的行 javascript

get line where selection is in javascript

我有一个 div contentEditable=true,其中输入了多行文本。每当用户按下回车键时,我想检查用户所在的行以查看该行(最好是所有行)的上下文。

是否可以有类似 window.getSelection().lineContent 的东西?

我可以使用window.getSelection().anchorNode.textContent,但它只适用于当前节点(不是该行)。我假设用户将按 enter 键转到下一行,我想知道下一行是否应该缩进(我的主要目标是知道行首是否有“制表符”,到目前为止)。

编辑:当前代码:

document.getElementById('sampleeditor').addEventListener("keydown", fSubsTab );

function fSubsTab () {      
    e = window.event
    if ( false ) {
    } else if ( e.keyCode == 13 ) {
        e.preventDefault();
        if (!window.getSelection) return;
        sel = window.getSelection();
        node_offset = sel.anchorOffset
        node_text = sel.anchorNode.textContent

        // The problem is how would I get the content of the
        // current line between last line break and next one,
        // or until the end
    }
}

编辑 2:已解决。请参阅下面的答案。

如果我正确理解了您的问题,您可以通过组合获得所需的行为:

  1. document.activeElement 获取活动文本元素
  2. document.activeElement.selectionStart获取光标位置
  3. document.activeElement.value.split("\n")[line] to convert cursor to the active line

document.addEventListener('keyup', (e) => {
  if (e.code === 'Enter' || e.code === 'NumpadEnter') {
    if (document.activeElement.type === 'textarea') {
      let start = $(document.activeElement).prop("selectionStart");
      let line = document.activeElement.value.substr(0, document.activeElement.selectionStart).split("\n").length - 2;
      console.log(`Pressed enter on line ${line + 1}:`);
      console.log(document.activeElement.value.split("\n")[line]);
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<textarea rows='5'>
foo
bar
foobar
barfoo
</textarea>

根据原始问题中列出的所有 parameters/rules,它的工作方式存在一些潜在问题。

最大的问题是使用 contentEditable 属性作为编辑 HTML 的方法。其他 solutions/examples 让你使用像 activeElementselectionStart 这样的东西。这很好,但您指出可以有 mixed 内容,例如 HTML 在某些情况下会改变活动元素。最初我想使用 innerTextinnerHTML 值,但这以更明显的方式提出了主要问题。

document.getElementById('sampleeditor').addEventListener("keyup", function(e) {
    if(e.keyCode == 13) {
      console.log(this.innerHTML.split("<div>")[this.innerHTML.split("<div>").length-1]);
      console.log(this.innerText.split("\n")[this.innerText.split("\n").length-1]);
    }
});
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry.</p>
<div id="sampleeditor" contentEditable=true>Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of <b><i>classical Latin literature</i></b> from 45 BC, making it over <span>2000 years old</span>.</div>
<p>The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested.</p>
<p>"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."</p>

在这个例子中,使用 innerText 可以让我们轻松地分隔每一行,但无法获取嵌入在主元素中的任何 HTML 代码。使用 innerHTML 也允许我们获得 HTML 代码,但是由于 contentEditable 的工作方式,这些行被一个简单的

标签分开,它也可以包含在元素内部并可能导致冲突。


替代方法

我不确定您可以使用现有代码执行的操作是否有任何限制因素,但我的建议是放弃 contentEditable 并加载