删除节点并按Enter键后,光标跳转到行尾(Firefox contenteditable)

时间:2018-04-26 14:57:40

标签: javascript html firefox contenteditable

我有这个代码从contenteditable元素中删除一个节点,但是如果我在删除节点后按 Enter ,光标会跳到行尾但不会破坏到新队。我能解决这个问题吗? (它在chrome中可以正常工作,但在firefox中没有。)

const button = document.getElementById('button');
const target = document.getElementById('target');

button.addEventListener('click', function() {
  const range = document.createRange();

  range.selectNode(target);
  range.deleteContents();
          
  const sel = window.getSelection();
  sel.removeAllRanges();
  sel.addRange(range);
});
<div class="wrapper" contenteditable="true">
    Click <span id="target">Button</span> then hit enter
</div>
<button id="button">go</button>

编辑:

似乎将问题内容包装在divp标记中可以解决问题,但是又出现了另一个问题,因为如果用户一直按退格删除 ctrl + a backsapace ...等可以删除包装标签。

2 个答案:

答案 0 :(得分:0)

什么浏览器不起作用? 似乎可以在IE 11,FF以及陈述的Chrome上使用。

你总是可以做一个关键的听众,让它做你想做的任何事情。

.onkeyup = function(e) {
    var key = e.keyCode ? e.keyCode : e.which;
    //13 is enter
    if (key === 13){       
       //Do work here.         
    }
}

答案 1 :(得分:0)

我终于设法解决了这个问题,不幸的是它非常hacky ...我真的讨厌满足:(希望这有助于任何与此斗争的人。

诀窍是将contenteditable的内容包含在divp标记内,遗憾的是仅此一项是不够的,因为用户在删除所有内容时可能会轻松删除该标记并继续点击退格删除甚至可以使用 ctrl + a 退格一次删除所有内容...等

因此,如果不存在,我们还需要确保插入包装器。

步骤:

  1. 添加keyup处理程序。
  2. 检查我们的包装是否存在。
  3. 如果确实如此,一切都很好。
  4. 如果不是:

    1. 以某种方式保存当前插入位置(我插入一个假元素以跟踪其位置)

    2. 创建我们的元素并将当前内容包装在其中。

    3. 恢复插入位置(并删除假元素)。
  5. 对于这么简单的事情来说,这是太多的工作,我真的希望我错了,并且存在一个更简单的解决方案。

    document.execCommand('defaultParagraphSeparator', false, 'p');
    
    const button = document.getElementById('button');
    
    button.addEventListener('click', function() {
      const range = document.createRange();
      const target = document.getElementById('target');
    
      range.selectNode(target);
      range.deleteContents();
    
      const sel = window.getSelection();
      sel.removeAllRanges();
      sel.addRange(range);
    });
    
    $('.wrapper').on('keyup', function(e) {
      if ($('.wrapper > p').length == 0) {
        pushCaretMarker();
        const html = '<p>' + $(this).html() + '<br></p>';
        $(this).html(html);
        popCaretMarker();
      }
    });
    
    function pushCaretMarker() {
      const range = getRange();
      const $span = $('<span id="caret-marker">|</span>');
      range.insertNode($span.get(0));
      range.collapse();
    }
    
    function popCaretMarker() {
      const $span = $('#caret-marker');
      if ($span.length > 0) {
        const range = getRange();
        range.selectNode($span.get(0));
    
        range.deleteContents();
      }
    }
    
    function getRange() {
      return window.getSelection().getRangeAt(0);
    }
    .wrapper {
      min-height: 20px;
    }
    
    .wrapper>p {
      margin: 0;
    }
    
    .wrapper>p:not(:last-child) {
      margin-bottom: 10px;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    <div class="wrapper" contenteditable="true">
      <p>
        Click <span id="target">Button</span> then hit enter
      </p>
    </div>
    <button id="button">go</button>