Contenteditable высота перехода: анимировать после добавления (Shift+ Enter) и удаления строки текста
Пока работает на использование contenteditable
атрибут на <div>
тег с функцией автоматического роста текстового поля. Также высота перехода этого. Все это работает хорошо, за исключением одной вещи: удаление символов, а именно строки, не будет анимировать ее высоту, в отличие от добавления новых строк. У меня еще немного знаний по CSS.
.autogrow {
border: 1px solid rgb( 0, 0, 0 );
padding: 10px;
}
@keyframes line_insert {
from {
height: 0px;
}
to {
height: 20px;
}
}
.autogrow[contenteditable] > div {
animation-duration: 250ms;
animation-name: line_insert;
}
.autogrow[contenteditable] {
overflow: hidden;
line-height: 20px;
}
<div class="autogrow" contenteditable="true"></div>
Когда я нажимаю Shift + Enter, он тоже не анимируется, но хорошо работает при нажатии Enter. Проблема заключается в удалении строк и комбинации клавиш Shift + Enter при вводе новой строки.
Как заставить это работать? Можно ли это сделать с использованием чистого CSS? Или добавить функцию JavaScript для него?
2 ответа
Чтобы избежать этих проблем, я лично использую решение, не основанное на чистых CSS-анимациях / переходах, которые, как я обнаружил, всегда имеют проблемы. Например, в вашей реализации CSS существует эффект возврата, если вы слишком быстро используете Enter (вы можете замедлить анимацию, чтобы лучше ее увидеть).
Более того, обработка новых строк в разных браузерах отличается, некоторые добавят <div><br></div>
, некоторые версии IE добавляют только <br>
, так далее.
Мне никогда не удавалось исправить все эти проблемы или я нашел реализацию, исправляющую все это, поэтому я решил вообще не изменять поведение contenteditable
Пусть браузер делает магию, которая работает и реагирует на происходящее.
Нам даже не нужно беспокоиться о событиях клавиш, таких как Shift + Enter или событиях, таких как удаление и т. Д., Все они изначально обрабатываются навигатором.
Вместо этого я выбрал 2 элемента: один для фактического contenteditable
и один для укладки моего contenteditable
который будет иметь анимацию / переходы высоты, основанные на фактической высоте contenteditable
,
Для этого я отслеживаю все события, которые могут изменить высоту contenteditable
и если высота моего элемента стиля не одинакова, я анимирую элемент стиля.
var kAnimationSpeed = 125;
var kPadding = 10;
$('div[contenteditable]').on('blur keyup paste input', function() {
var styleElement = $(this).prev();
var editorHeight = $(this).height();
var styleElementHeight = styleElement.height();
if (editorHeight !== styleElementHeight - kPadding * 2) {
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>
Это вроде хаки, но это работает.
Во-первых, измените свой CSS
.autogrow {
border: 1px solid rgb( 0, 0, 0 );
padding: 10px;
}
@keyframes line_insert {
from {
height: 0px;
}
to {
height: 20px;
}
}
.autogrow[contenteditable] > div {
animation-duration: 250ms;
animation-name: line_insert;
}
.autogrow[contenteditable] {
overflow: hidden;
line-height: 20px;
}
Затем добавьте этот jQuery, который обнаруживает события Shift + Enter и добавляет div, когда они происходят.
$(".autogrow").keydown(function(e){
if (e.keyCode == 13 && e.shiftKey || e.keyCode == 13)
{
$(this).animate({height: $(this).height()+20},200);
$(this).append('<div><br></div>');
}
});
И это должно работать.
Проверьте скрипку https://jsfiddle.net/wx38rz5L/582/