微信号:FrontDev

介绍:分享 Web 前端相关的技术文章、工具资源、精选课程、热点资讯

案例:根据文本域内容自动调整高度

2015-01-09 20:21 前端大全
点击上方蓝字↑↑↑,轻松关注哦~

在用一个简单的Web端的 Markdown 编辑器时,我需要一个能让用户输入文本的东西。我首先想到的是使用一个具有可编辑属性的DIV。但是这种方式引入了许多我不想去解决的问题。我仅仅需要一种简单傻瓜式的方案——美好的TEXTAREA。


但是文本域同样也有一个大问题:它们会有一个默认的固定高度。你可以设置 rows 属性来告诉页面该展示多少行,也可以设置文本域的 style.height 属性。但不幸的是,文本域没有自动设置高度(auto-height)的属性。


我的想法


在每次改变文本时,我们必须计算内容的高度是多少。幸运的是,有个办法可以实现。element.scrollHeight可以忽略可见滚动条,得到内容的高度。为了减小(文本域)尺寸我们每次将高度设置为0,这样scrollHeight就返回所需要的最小高度而不会多余。例如:当用户删除一行的时候。


同样我们需要计算边框(border)和轮廓(outline)的尺寸,这样文本就不会被截断,也不会出现滚动条。


然后我们设置style.height属性为已经计算好的高度。


为了每次都执行上面的动作,我们使用oninput事件,这个事件在每次文本内容改变时被触发。这与onchange事件相反,onchange只会在用户点击时触发。


看看代码


<textarea data-adaptheight rows="3" cols="40" placeholder="Your input"

style="padding: 16px; line-height: 1.5;"></textarea>

<script>

(function() {

function adjustHeight(textareaElement, minHeight) {

// compute the height difference which is caused by border and outline

// 计算因边框和轮廓产生的高度差异

var outerHeight = parseInt(window.getComputedStyle(el).height, 10);

var diff = outerHeight - el.clientHeight;

// set the height to 0 in case of it has to be shrinked

// 设置高度为0以防需要收缩(高度)

el.style.height = 0;

// set the correct height

// el.scrollHeight is the full height of the content, not just the visible part

// 设置正确的高度

// el.scrollHeight 是文本内容的全部高度,而不仅仅是可见部分的。

el.style.height = Math.max(minHeight, el.scrollHeight + diff) + 'px';

}

// we use the "data-adaptheight" attribute as a marker

// 我们使用"data-adaptheight"属性作为一个标记

var textAreas = document.querySelectorAll('textarea[data-adaptheight]');

// iterate through all the textareas on the page

// 迭代本页所有的文本域

for (var i = 0, l = textAreas.length; i &lt; l; i++) {

var el = textAreas[i];

// we need box-sizing: border-box, if the textarea has padding

// 如果文本域有边距,我们需要设置box-sizing: border-box

el.style.boxSizing = el.style.mozBoxSizing = 'border-box';

// we don't need any scrollbars, do we? <img src="http://web.jobbole.com/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley">

// 我们不需要滚动条,不是么? <img src="http://web.jobbole.com/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley">

el.style.overflowY = 'hidden';

// the minimum height initiated through the "rows" attribute

// 通过"rows"属性初始化的最小高度

var minHeight = el.scrollHeight;

el.addEventListener('input', function() {

adjustHeight(el, minHeight);

});

// we have to readjust when window size changes (e.g. orientation change)

// 当窗口大小改变时,我们需要重新调整高度(例如方向变化)

window.addEventListener('resize', function() {

adjustHeight(el, minHeight);

});

// we adjust height to the initial content

// 我们调整初始内容的高度

adjustHeight(el, minHeight);

}

}());

</script>


示例


输入一些文本体验下。初始高度为3行。

http://jsfiddle.net/5h4fauq8/1/


权衡


每次键盘事件都会造成页面重绘。因为我们会设置文本域的高度为0然后设置为计算的值。然而这是可以忽略的,因为大多数用户在一秒之内最多只能打几个字。因此这不会造成任何明显的性能缺陷。


在何处使用?


在许多场景下这个都是有用的。其中包括:


  • 文本编辑器

  • 代码编辑器

  • 评论框



原文出处: bdadam.com

译文出处:伯乐在线 - 袁璋


/////////////////


1. 『前端大全』分享 Web 前端相关的技术文章、工具资源、精选课程、热点资讯,欢迎关注。微信号:FrontDev

2. 点击“阅读原文”,查看更多前端文章。


 
前端大全 更多文章 5个典型的JavaScript面试题(上) Limu:JavaScript的那些书 Web开发:我希望得到的编程学习路线图 JavaScript基础工具清单 常用排序算法之JavaScript实现
猜您喜欢 谁是Tomcat? 干嘛的? 微软“.Net社区虚拟大会”dotnetConf2015:关键词:.NET 创新、开源、跨平台 蒙特卡罗模拟 YouTube抛弃Flash,将HTML5视频设为默认 PHP100大讲堂:PHP5面向对象编程入门(6月18号晚7点 第二讲)