将内容可编辑元素替换为有序列表时保持可编辑性

Retain editability upon replacing contentEditable element with ordered list

本文关键字:编辑 列表 元素 替换      更新时间:2023-09-26

Background

尝试使用内容可编辑<div>编辑有序列表。希望粘贴任何内容、键入任何内容或删除任何内容,并始终显示至少一个有序列表项,但从不显示任何其他类型的文本(例如,没有空行、没有引用文本、没有缩进、没有来自 Microsoft Word 的字体等(。

使用 jQuery 1.9.1 支持尽可能多的浏览器。小提琴有下面的源代码。

法典

JavaScript (jQuery(:

$(document).ready(function() {
  $('.directions > ol').prop('contentEditable','true');
  $('.directions > ol').keydown( function( e ) {
    // Prevent shift-enter from creating blank lines.
    if( e.keyCode === 13 && e.shiftKey ) {
      e.preventDefault();
    }
  });
  $('body').on( 'focus', '[contenteditable]', function() {
    var $this = $(this);
    $this.data( 'before', $this.html() );
    return $this;
  }).on( 'paste blur input keyup', '[contenteditable]', function( e ) {
    var $this = $(this);
    if( $this.data('before') !== $this.html() ) {
      $this.data( 'before', $this.html() );
      $this.trigger( 'change' );
    }
  });
  $('.directions > ol').on( 'change', function( e ) {
    var fragment = $(this).clone();
    fragment.find( 'br' ).replaceWith( "'n" );
    var div = document.createElement( 'div' );
    var text = fragment.text().replace( /['r'n]+/g, ''n' );
    text = '<ol><li>' + text.replace( /'n/g, '</li><li>' ) + '</li></ol>';
    $(this).replaceWith( text );
  });
});

该 HTML:

<html>
<body>
<div class="directions">
  <ol>
    <li>Turn left onto 5th Street after 500m.</li>
  </ol>
</div>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="js/list.js" charset="utf-8"></script>
</body>
</html>

问题

替换内容可编辑<ol>时:

$(this).replaceWith( text );

将删除以下事件绑定:

$('.directions > ol').prop('contentEditable','true');
.on( 'paste blur input keyup', '[contenteditable]', function( e ) {

问题

我的主要问题是:如何在不破坏contenteditable绑定的情况下替换内部<ol>内容 - 以便用户可以继续编辑内容,即使他们选择整个文本来替换它?

我的第二个问题是:这甚至是一个可行的方法吗?我研究了各种所见即所得的实现。它们看起来都相当复杂,并且对于这样一个看似简单的任务有一个巨大的足迹(除了Whizzywing(。

jQuery可能会产生这样的意外副作用。有时,即使有jQuery快捷方式,使用常规JavaScript也会更好。

我在上面发布的jsfiddle中对此进行了测试。替换该行:

$(this).replaceWith( text );

document.getElementById(this).innerHTML = text;

我尝试使用 jQuery .html(( 命令,它没有删除绑定,但它确实将文本光标移动到行首。

更新:在Chrome 29,Firefox 24和IE9中测试。效果很好。