contenteditable 高度动画:仅在删除一行后动画

Posted

技术标签:

【中文标题】contenteditable 高度动画:仅在删除一行后动画【英文标题】:Contenteditable height animation: animate only after a line is deleted 【发布时间】:2016-12-14 22:04:04 【问题描述】:

这是我之前question的延续。

我设法通过添加条件e.which === 13 来修复“动画在每次连续击键时暂停”,该条件会在按下 Enter 键时检测并生成动画。


这是上一个的工作原理:

如您所见,在输入换行符然后连续击键后,动画滞后,这意味着动画在每次击键时执行。


这些是修改后的,只有在按下 Enter 后才会动画:

它工作顺利(虽然在录制过程中有点滞后)。


这是删除每个字符时的工作原理(不是长按):

如您所见,动画效果不佳,因为当您连续删除每个角色时,动画会暂停,就像第一次尝试一样。


所以我现在想要实现的是相反的,在删除换行符后平滑动画。

这是一个实时代码:

var kAnimationSpeed = 250;
var kPadding = 10;

$('div[contenteditable]').on('blur keyup paste input', function(e) 
  var styleElement = $(this).prev();

  var editorHeight = $(this).height();
  var styleElementHeight = styleElement.height();

  if (editorHeight !== styleElementHeight - kPadding * 2 && e.which === 13 || e.which === 8) 
    styleElement.stop().animate( height: editorHeight + kPadding * 2 , kAnimationSpeed);
  
);
.autogrowWrapper 
  position: relative;


.autogrow 
  border: 1px solid rgb(0, 0, 0);
  height: 40px; /* line-height + 2 * padding */


div[contenteditable] 
  outline: none;
  line-height : 20px;
  position: absolute;
  top: 10px; /* padding */
  left: 10px; /* padding */
  right: 10px; /* padding */
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="autogrowWrapper">
  <div class="autogrow"></div>
  <div contenteditable="true"></div>
</div>

如何在删除换行符时实现流畅的动画,或者如何仅在删除换行符时进行动画处理?

【问题讨论】:

在您的if 语句中,尝试添加类似if ( ! $(this).is(':animated') ) 的内容,因为延迟可能是在第一次调用stop() 等之后多次调用动画。跨度> 当我使用 &amp;&amp; 运算符添加该条件时,仍然相同。但是当我尝试||运算符时,它会影响输入过程。这意味着它在上一次尝试中的工作方式相同。 :v 可能是这样的 jsfiddle.net/yfSUk/3 但用 left 代替 top 并且当值更改时继续播放动画 ***.com/questions/13347471/… @Squirrl 如何获得换行符? 【参考方案1】:

我不知道这是否适用于跨浏览器,但 Chrome 为行添加了 &lt;div&gt;s,因此您实际上可以计算它们:

working fiddle

var kAnimationSpeed = 250;
var kPadding = 10;
var keyCodeDelete = 8;
var keyCodeReturn = 13;

$('div[contenteditable]').on('blur keyup paste', function(e) 
  var el = $(this);
  var styleElement = el.prev();
  var editorHeight = el.height();
  var styleElementHeight = styleElement.height();

  var divCount = parseInt(el.data('divcount') || 0 );
  var newDivCount = el.children('div').not(':contains("br")').length;
  var newLineDeleted = (divCount - 1 == newDivCount && e.which == keyCodeDelete);

  var heightCheck = (editorHeight !== styleElementHeight - kPadding * 2);
  var keyCodeCheck = (e.which === keyCodeReturn || e.which === keyCodeDelete);


  if (heightCheck && keyCodeCheck) 
    if (newLineDeleted) 
      $('body').append('<p>nl removed!</p>');
    
    styleElement.stop().animate( height: editorHeight + kPadding * 2 , kAnimationSpeed);
  

  el.data('divcount', newDivCount);
);

所以你只需要调整你的动画:)

【讨论】:

我试过你的代码,但还是一样。但我从你的代码中得到了一个想法。我将进行一些调整并使用您的代码的某些部分。感谢您的回答。 :) 我有一个问题。如何计算&lt;br&gt; 而不是&lt;div&gt;【参考方案2】:

所以我设法根据 Alex 的回答解决了这个问题。

在他的回答中,它仅在按下 Enter 键时有效。但我的目标是使用 Shift + Enter。按 Enter 将在 contenteditable div 中插入新的 &lt;div&gt;,而 Shift + Enter 插入新的 &lt;br&gt; 而不是 @ 987654326@。所以我修改了将计数&lt;br&gt;的代码,将值存储到数据中,并比较当前行数是否小于新行数,并监听 Backspace 键。然后我将e.which === 8 替换为newLineDeleted 变量,以告知何时删除了新行。并删除 input 函数,使其返回准确的布尔值(因为它似乎不适用于其中的 input 函数。我还添加了剪切和粘贴侦听器。

var kAnimationSpeed = 250;
var kPadding = 10;

$('div[contenteditable]').on('blur keyup paste', function(e) 
  var styleElement = $(this).prev();
  var editorHeight = $(this).height();
  var styleElementHeight = styleElement.height();
  
  var lineCount = parseInt($(this).data('linecount') || 0);
  var newLineCount = $(this).children('br').length;
  $(this).data('linecount', newLineCount);
  var newLineDeleted = (lineCount - 1 === newLineCount && e.which === 8);
  
  var cutPasteListener = (e.ctrlKey && e.which === 86 || e.which === 88);

  if (editorHeight !== styleElementHeight - kPadding * 2 && e.which === 13 || newLineDeleted || cutPasteListener) 
    styleElement.stop().animate( height: editorHeight + kPadding * 2 , kAnimationSpeed);
  
);
.autogrowWrapper 
  position: relative;


.autogrow 
  border: 1px solid rgb(0, 0, 0);
  height: 40px; /* line-height + 2 * padding */


div[contenteditable] 
  outline: none;
  line-height : 20px;
  position: absolute;
  top: 10px; /* padding */
  left: 10px; /* padding */
  right: 10px; /* padding */
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="autogrowWrapper">
  <div class="autogrow"></div>
  <div contenteditable="true"></div>
</div>

谢谢。

【讨论】:

以上是关于contenteditable 高度动画:仅在删除一行后动画的主要内容,如果未能解决你的问题,请参考以下文章

删除和插入具有不同高度的单元格时,UITableView 动画故障

删除高度大于其他单元格的单元格时,动画看起来很尴尬

contenteditable设置元素可编辑

如何让contenteditable元素只能输入纯文本

如何让contenteditable元素只能输入纯文本 00 张鑫旭

如何在contenteditable div中删除非contenteditable div