众所周知scrollHeight不可信,这样我们就要寻找一个可信的height标准。我们另外创建一个div,让它的css完全继承自这个textarea,因为div的height是可以自由浮动伸缩的,所以我们截获textarea的keyup事件,然后把它的内容发送到div里,然后我们通过获取div的高度来定义textarea的高度。

在实现这个功能之前,还有个需要实现的功能,那就是拷贝css到另一个元素,索性网上已经有现成的jQuery解决方案。

// 获取一个元素的所有css属性的patch, $(el).css()jQuery.fn.css2 = jQuery.fn.css;jQuery.fn.css = function() {  
  if (arguments.length) return jQuery.fn.css2.apply(this, arguments);  
  var attr = [\'font-family\',\'font-size\',\'font-weight\',\'font-style\',\'color\',   
     \'text-transform\',\'text-decoration\',\'letter-spacing\', \'box-shadow\',      
  \'line-height\',\'text-align\',\'vertical-align\',\'direction\',\'background-color\',    
    \'background-image\',\'background-repeat\',\'background-position\',      
  \'background-attachment\',\'opacity\',\'width\',\'height\',\'top\',\'right\',\'bottom\',       
 \'left\',\'margin-top\',\'margin-right\',\'margin-bottom\',\'margin-left\',    
    \'padding-top\',\'padding-right\',\'padding-bottom\',\'padding-left\',     
   \'border-top-width\',\'border-right-width\',\'border-bottom-width\',      
  \'border-left-width\',\'border-top-color\',\'border-right-color\',      
  \'border-bottom-color\',\'border-left-color\',\'border-top-style\',    
    \'border-right-style\',\'border-bottom-style\',\'border-left-style\',\'position\',   
     \'display\',\'visibility\',\'z-index\',\'overflow-x\',\'overflow-y\',\'white-space\',    
    \'clip\',\'float\',\'clear\',\'cursor\',\'list-style-image\',\'list-style-position\',     
   \'list-style-type\',\'marker-offset\'];   
 var len = attr.length, obj = {};  
 for (var i = 0; i < len; i++)     
    obj[attr[i]] = jQuery.fn.css2.call(this, attr[i]);  
  return obj;};
有了这两个代码,我们就可以来实现了
$(\'textarea\').keyup(function () { 
   var t = $(this);       
 if (!this.justifyDoc) {   
     this.justifyDoc = $(document.createElement(\'div\'));

        // copy css     
   this.justifyDoc.css(t.css()).css({     
       \'display\'   :   \'block\',      
  // you can change to none        
    \'word-wrap\' :   \'break-word\',      
      \'min-height\':   t.height(),         
   \'height\'    :   \'auto\'        }).insertAfter(t.css(\'overflow-y\', \'hidden\'));    }

    var html = t.val().replace(/&/g, \'&amp;\')    
    .replace(/</g, \'&lt;\')       
 .replace(/>/g, \'&gt;\')    
    .replace(/\'/g, \'&#039;\')      
  .replace(/"/g, \'&quot;\')     
   .replace(/ /g, \'&nbsp;\')   
    .replace(/((&nbsp;)*)&nbsp;/g, \'$1 \')     
   .replace(/\\n/g, \'<br />\')      
  .replace(/<br \\/>[ ]*$/, \'<br />-\')    
    .replace(/<br \\/> /g, \'<br />&nbsp;\');

    this.justifyDoc.html(html);   
 t.height(this.justifyDoc.height());});