Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

文本域根据内容自动计算高度

  今天修改了下网站后台的代码,感觉文本域固定高度的话编辑文章很不爽,所以就想了个办法就把它做成根据内容自动调整高度的。没想到这东西还相当复杂,虽然用起来没啥问题,但是感觉在细节的处理上还有一些不足。目前就这样啦,不喜勿喷~
  HTML的控件都比较死板,文本域也不例外。即使设置了高度为auto也无法自适应内容高度,所以我们只能通过JavaScript来实现。要计算内容文本的高度可没那么容易,我们只能另外创建个可以自动高度的容器来计算。而普通的容器比如DIV,是不会解析换行的,如果用HTML转义,那每次计算高度需要消耗的资源就大的多了。因此只能用PRE或XMP,XMP这个标签已经不建议使用了,咱就不用它了,就用PRE来做。当用户在文本域编辑内容时候,把编辑完的内容放入一份到一个隐藏的PRE容器中,获取PRE容器的高度再设置回文本域上。这个思路虽然简单,但是要注意很多问题。隐藏PRE的时候不能直接“display:none”要不然无法获取到高度;PRE的样式得设置的和文本域相同,如果不同,文字换行的位置就会有偏差;样式中也有一些属性要注意,比如“word-break”和“word-wrap”都需要设置上。这些细节的问题说不完了,还是直接看代码吧 <!DOCTYPE html>
<style>
.txt {
  border:1px solid #CCC;width:200px;padding:3px;
  font:12px/16px Simsun;outline:none;resize:none;
  word-wrap:break-word;word-break:break-all;
  overflow:hidden;
}
</style>
<textarea id="o" class="txt">来呀,来编辑我呀~</textarea>
<script>
(function(o,e,t){
  //创建一个pre标签,用来计算文字应有高度
  e=document.createElement("pre");
  //给pre添加上和文本域一样的样式
  e.className="txt";
  //设置绝对定位到屏幕外来隐藏它
  e.style.position="absolute";
  e.style.left="-9999px";
  //创建一个文本节点来操作,避免直接操作HTML
  e.appendChild(t=document.createTextNode(""));
  //给pre的末尾添加一个换行,因为pre会吞掉末尾的一个换行
  e.appendChild(document.createTextNode("\n"));
  //把pre放入文档中
  document.body.appendChild(e);
  //文本域键盘事件时计算高度
  o.onkeydown=o.onkeyup=function(){
    //IE8下\r\n在PRE标签中会被解析为两行,所以需要一个替换
    //如果觉得这样会影响效率可以先判断浏览器
    t.data=o.value.replace(/\r\n/g,"\n");
    o.style.height=e.offsetHeight-8+"px";
  };
  //初始时计算一次
  o.onkeydown();
  //为了避免换行时闪的太厉害,稍微阻止下滚动
  o.onscroll=function(){o.scrollTop=0};
})(document.getElementById("o"));
</script>
  这个代码使用上倒是没啥问题,但是换行的闪烁貌似无法避免,咱只能给它降低到最小了。当然也许一些蛋疼的方法,比如用容器暂时挡住闪烁的文本框,不过这个想法只是瞬间冒过脑残而已。这要去这样实现,一定是蛋疼到极点的人才会做的事情。另外,这个代码中为了方便我只用了键盘事件来判断编辑,如果用鼠标右键菜单粘帖就要悲剧了。这个问题可以在focus和blur两个事件中开关一个计时器来扫描解决。可以参考以前“模拟PlaceHolder”的代码。
网名:
3.80.32.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^