При создании HTML-элементов ‹textarea› вы можете захотеть, чтобы его высота соответствовала количеству содержимого внутри него. Например, если элемент ‹textarea› содержит 3 строки текстового содержимого, вы можете захотеть, чтобы ‹textarea› было 3 строки длиной, что будет ` rows = «3» `в HTML или` height: 3em `в CSS.
Проблема с элементами ‹textarea› в том, что количество их содержимого меняется. Я думал, что CSS может автоматически изменять размер элементов ‹textarea›, чтобы соответствовать их содержимому (например, `height: auto`), но это невозможно. В настоящее время. Однако это возможно с помощью JavaScript.
Я нашел несколько замечательных примеров, в которых используются как jQuery, так и стандартные методы DOM:
http://stackoverflow.com/questions/454202/creating-a-textarea-with-auto-resize/5346855#5346855
Я пытался сделать это с помощью Mithril, и, поскольку это довольно новый фреймворк / библиотека, я покажу, как я это сделал.
Вот начальная настройка компонента Mithril, в котором используется элемент ‹textarea›.
m.route(document.body, '/', { '/': Text }); var Text = { controller: function() { var ctrl = this; ctrl.text = ''; }, view: function(ctrl) { return m('#Text', [ m('textarea.text-class[placeholder="Dime!"]', { value: ctrl.text, onchange: function(e) { e.preventDefault(); ctrl.text = e.currentTarget.value; } }), ]); } };
Во-первых, мы можем добавить прослушиватель событий к событию keyup« и вставить одну из функций автоматического изменения размера, описанных в «ссылке выше.
m.route(document.body, '/', { '/': Text }); var Text = { controller: function() { var ctrl = this; ctrl.text = ''; }, view: function(ctrl) { return m('#Text', [ m('textarea.text-class[placeholder="Dime!"]', { value: ctrl.text, onchange: function(e) { e.preventDefault(); ctrl.text = e.currentTarget.value; }, onkeyup: function(e) { e.preventDefault(); e.target.style.height = 'auto'; e.target.style.height = e.target.scrollHeight + 'px'; }), ]); } };
Это довольно легко реализовать. Однако в этом методе есть небольшая ошибка. Если исходный текст внутри элемента ‹textarea› не пуст, когда Mithril создает объект, он не будет автоматически изменять размер, поэтому сбоку появится полоса прокрутки. В Mithril вы можете редактировать элемент, как только он прикреплен к DOM, установив атрибут config «, который чем-то похож на событие« oninit «. listener или метод getInitialState в React.
m.route(document.body, '/', { '/': Text }); var Text = { controller: function() { var ctrl = this; ctrl.text = 'this\nis\nsome\nlong\ntext\nwith\nno\npurpose'; }, view: function(ctrl) { return m('#Text', [ m('textarea.text-class[placeholder="Dime!"]', { value: ctrl.text, onchange: function(e) { e.preventDefault(); ctrl.text = e.currentTarget.value; }, config: function(el, isInitialized, context) { if ( ! isInitialized ) { el.style.height = 'auto'; el.style.height = el.scrollHeight + 'px'; } }, onkeyup: function(e) { e.preventDefault(); e.target.style.height = 'auto'; e.target.style.height = e.target.scrollHeight + 'px'; }), ]); } };
Затем, чтобы немного очистить это, мы можем выделить логику автоматического изменения размера в отдельную функцию.
m.route(document.body, '/', { '/': Text }); var Text = { controller: function() { var ctrl = this; ctrl.text = 'this\nis\nsome\nlong\ntext\nwith\nno\npurpose'; }, view: function(ctrl) { return m('#Text', [ m('textarea.text-class[placeholder="Dime!"]', { value: ctrl.text, onchange: function(e) { e.preventDefault(); ctrl.text = e.currentTarget.value; }, config: function(el, isInitialized, context) { if ( ! isInitialized ) { autoResizeTextarea(el); } }, onkeyup: function(e) { e.preventDefault(); autoResizeTextarea(e.target); }), ]); } }; function autoResizeTextarea(el) { el.style.height = 'auto'; el.style.height = el.scrollHeight + 'px'; }
Чтобы сделать это еще интереснее, вот пример использования некоторых вспомогательных функций, которые я использую повсюду с Mithril:
m.route(document.body, '/', { '/': Text }); var Text = { controller: function() { var ctrl = this; ctrl.text = 'this\nis\nsome\nlong\ntext\nwith\nno\npurpose'; }, view: function(ctrl) { return m('#Text', [ m('textarea.text-class[placeholder="Dime!"]', { value: ctrl.text, onchange: function(e) { e.preventDefault(); ctrl.text = e.currentTarget.value; }, config: initEl(autoResizeTextarea), onkeyup: editEl(autoResizeTextarea) } ]); } }; function initEl(cb) { return function(el, isInitialized, context) { if ( ! isInitialized ) { cb(el); } }; } function editEl(cb) { return function(e) { e.preventDefault(); cb(e.target); }; } function autoResizeTextarea(el) { el.style.height = 'auto'; el.style.height = el.scrollHeight + 'px'; }