【问题标题】:How to get focus on new block in a contenteditable div?如何专注于内容可编辑 div 中的新块?
【发布时间】:2020-12-23 21:52:54
【问题描述】:

我正在使用 contenteditable div 创建一个文本编辑器。当有人按下Enter 键时,它会创建一个新块,现在我需要专注于新块,并且我想在这个新块上添加一个新类.is-focused

[注意]:我使用 javascript 作为新块,因为它只是在默认的 contenteditable 行为下复制前一个块。我不需要前一个区块,但需要一个全新的区块。

let

  root = document.querySelector('.root'),
  old_block = document.querySelectorAll('.block'),
  dummy_id = 2;

root.addEventListener('keydown', (e) => {
  if (e.key !== 'Enter')
    return;

  e.preventDefault();
  dummy_id++;

  let template =
    `<div id="block-${dummy_id}" class="block">Block ${dummy_id}</div>`;
  root.insertAdjacentHTML('beforeend', template);

  document.querySelector(`#block-${dummy_id}`).focus();
})
*,
*::before,
*::after {
  box-sizing: border;
}

body {
  margin: 0;
}

.root {
  max-width: 700px;
  margin: 1rem auto;
}

.root:focus {
  outline: 0;
}

.block {
  font-size: 21px;
  line-height: 1.8;
  color: rgba(0, 0, 0, .83)
}

.is-focused {
  background-color: rgb(240, 254, 255);
}
<div class="root" contenteditable="true">
  <div id="block-1" class="block">Block 1 [Paragraph]</div>
  <div id="block-2" class="block">Block 2 [IMG]</div>
</div>

【问题讨论】:

标签: javascript


【解决方案1】:

以前遇到过同样的问题,这是我从极客那里得到的解决方案;

let

  root = document.querySelector('.root'),
  old_block = document.querySelectorAll('.block'),
  dummy_id = 2;

root.addEventListener('keydown', (e) => {
  if (e.key !== 'Enter')
    return;

  e.preventDefault();
  dummy_id++;

  let template =
    `<div id="block-${dummy_id}" class="block" contenteditable="true" tabindex="-1">Block ${dummy_id}</div>`;
  root.insertAdjacentHTML('beforeend', template);

  newBlock = document.querySelector(`#block-${dummy_id}`)
  pos = document.createRange();
  s = window.getSelection();
  pos.setStart(newBlock.childNodes[0], `Block-${dummy_id}`.length);
  pos.collapse(true);
  s.removeAllRanges();
  s.addRange(pos);
})

.focus() 实际上选择了整个 div,而是使用范围。你可以通过改变来设置你想要的任何位置

pos.setStart(newBlock.childNodes[0], `Block-${dummy_id}`.length);

您可以阅读有关使用范围的更多信息;这里:https://www.geeksforgeeks.org/how-to-set-cursor-position-in-content-editable-element-using-javascript/

【讨论】:

    【解决方案2】:
    • 是的,通过聚焦,您的意思是在新块上设置一个光标
    • 这可以通过选择范围(用于处理光标位置)来实现。

    这是一个有效的小提琴:https://jsfiddle.net/hp5L02v7/7/

    function placeCursorInRichText(el, selector) {
        var range = document.createRange();
        var sel = window.getSelection();
        range.setStart(el.querySelector(selector), 0);
        range.collapse(true);
        sel.removeAllRanges();
        sel.addRange(range);
    }
    
    placeCursorInRichText(root, "#block-3");
    

    【讨论】:

      【解决方案3】:

      div 元素默认不接收焦点。但是,您可以给它一个 tabindex 属性来实现这种行为。 Read more

      tabindex="-1" 表示div 只能通过脚本聚焦。 这是一个仅涉及元素聚焦的解决方案。

      let
      
        root = document.querySelector('.root'),
        old_block = document.querySelectorAll('.block'),
        dummy_id = 2;
      
      root.addEventListener('keydown', (e) => {
        if (e.key !== 'Enter')
          return;
      
        e.preventDefault();
        dummy_id++;
      
        let template =
          `<div id="block-${dummy_id}" tabindex="-1" class="block">Block ${dummy_id}</div>`;
      
        root.insertAdjacentHTML('beforeend', template);
        document.querySelector(`#block-${dummy_id}`).focus();
      })
      *,
      *::before,
      *::after {
        box-sizing: border;
      }
      
      body {
        margin: 0;
      }
      
      .root {
        max-width: 700px;
        margin: 1rem auto;
      }
      
      .root:focus {
        outline: 0;
      }
      
      .block {
        font-size: 21px;
        line-height: 1.8;
        color: rgba(0, 0, 0, .83)
      }
      
      .is-focused {
        background-color: rgb(240, 254, 255);
      }
      <div class="root" contenteditable="true">
        <div id="block-1" class="block">Block 1 [Paragraph]</div>
        <div id="block-2" class="block">Block 2 [IMG]</div>
      </div>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-03-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多