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

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

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

我的想法

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

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

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

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

看看代码

示例

输入一些文本体验下。初始高度为3行。
http://jsfiddle.net/5h4fauq8/1/

权衡

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

在何处使用?

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

  • 文本编辑器
  • 代码编辑器
  • 评论框

你喜欢这个么? 你已经在使用了么? 就在下面进行评论吧。:)

打赏支持我翻译更多好文章,谢谢!

打赏译者

打赏支持我翻译更多好文章,谢谢!

收藏 4 评论

关于作者:yuanzhang

#Java 开发#js 个人主页 · 我的文章 · 11 ·   

可能感兴趣的话题



直接登录
最新评论
  • 其中
    // 迭代本页所有的文本域
    for (var i = 0, l = textAreas.length; i < l; i++) {
    }
    循环里面的显示有误,应该是
    for (var i = 0, l = textAreas.length; i < l; i++) {
    }

  • raku   2015/02/05

    // set the height to 0 in case of it has to be shrinked
    // 设置高度为0以防需要收缩(高度)
    el.style.height = 0;

    为什么会收缩啊
    我发现不设置这个 在清除的时候scrollHeight会不正确 但是不明白原因, 求指教!

    • yuanzhang JAVA 2015/06/01

      – 为什么会收缩
      说的是以防需要收缩,因为删除文本时,需要动态收缩高度,这个意思;

      – 如果不设置style.height = 0,则scrollHeight不会重新计算,所以不会出现收缩;
      关于几个高度,参考:http://stackoverflow.com/questions/22675126/what-is-offsetheight-clientheight-scrollheight

跳到底部
返回顶部