2008-08-11 30 views
106

我目前正在爲我工​​作的公司開發內部銷售應用程序,並且我有一個允許用戶更改送貨地址的表單。使用Prototype自動設置textarea

現在我認爲它看起來會更好,如果我用於主地址細節的textarea只佔用其中文本的區域,並在文本發生更改時自動調整大小。

下面是當前的截圖。

ISO Address

任何想法?


@克里斯

好點,但也有原因,我希望它來調整。我想要它佔據的區域成爲其中包含的信息的區域。正如你在屏幕截圖中看到的那樣,如果我有一個固定的textarea,它會佔用垂直空間的一大筆費用。

我可以減少字體,但我需要的地址大而可讀。現在我可以縮小文本區域的大小,但是對於地址線需要3或4(一條需要5條)線的人,我遇到了問題。需要讓用戶使用滾動條是一個主要的禁忌。

我想我應該更具體一點。我在垂直調整大小之後,寬度並不重要。唯一遇到的問題是,當窗口寬度太小時(正如您在屏幕截圖中看到的那樣),ISO編號(大「1」)會在地址下被推入。

這不是要有一個gimick;這是關於讓用戶編輯的文本字段不會佔用不必要的空間,但會顯示其中的所有文本。

雖然如果有人想出另一種方法來解決這個問題,我也接受。


我修改了一些代碼,因爲它有點奇怪。我將它改爲在keyup上激活,因爲它不會考慮剛輸入的字符。

resizeIt = function() { 
    var str = $('iso_address').value; 
    var cols = $('iso_address').cols; 
    var linecount = 0; 

    $A(str.split("\n")).each(function(l) { 
    linecount += 1 + Math.floor(l.length/cols); // Take into account long lines 
    }) 

    $('iso_address').rows = linecount; 
}; 
+0

你可以創建一個演示網站,我們可以在工作中看到這個嗎? – einar 2012-08-14 13:26:29

+3

這個插件看起來不錯http://www.jacklmoore.com/autosize – 2012-11-27 10:26:05

+0

有沒有JQuery版本?如何在JQuery中訪問TextArea的列和行? – Zach 2012-12-18 08:47:59

回答

68

Facebook的確如此,當你在人們的牆上寫字時,只能垂直調整大小。

水平調整大小打亂了我作爲一個混亂,由於文字換行,長行等,但垂直調整大小似乎是非常安全和好。

我所知道的Facebook使用新手都沒有提到過任何關於它或被弄糊塗。我會用這個軼事證據來說'繼續,實施它'。

一些JavaScript代碼來做到這一點,利用Prototype(因爲這是我所熟悉的):

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
    "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
    <head> 
     <script src="http://www.google.com/jsapi"></script> 
     <script language="javascript"> 
      google.load('prototype', '1.6.0.2'); 
     </script> 
    </head> 

    <body> 
     <textarea id="text-area" rows="1" cols="50"></textarea> 

     <script type="text/javascript" language="javascript"> 
      resizeIt = function() { 
       var str = $('text-area').value; 
       var cols = $('text-area').cols; 

       var linecount = 0; 
       $A(str.split("\n")).each(function(l) { 
        linecount += Math.ceil(l.length/cols); // Take into account long lines 
       }) 
       $('text-area').rows = linecount + 1; 
      }; 

      // You could attach to keyUp, etc. if keydown doesn't work 
      Event.observe('text-area', 'keydown', resizeIt); 

      resizeIt(); //Initial on load 
     </script> 
    </body> 
</html> 

PS:很顯然,這段JavaScript代碼是很幼稚,沒有得到很好的測試,你可能穿上」我不想在有小說的文本框中使用它,但是你得到了一般想法。

+2

這假設瀏覽器中斷任何字符,這是不正確的。試試``。 (我寫了一個幾乎完全相同的實現,直到使用它一個月後才發現它)。它也沒有空行。 – 2012-09-21 11:03:45

+0

有沒有這個JQuery版本? – Emerald214 2015-09-28 07:56:34

36

下面是另一種自動調整文本區域的方法。

  • 使用像素高度代替線高度:如果使用比例字體,則會更精確地處理換行。
  • 接受ID或元素作爲輸入
  • 接受可選的最大高度參數 - 如果您不希望文本區域增長超過特定大小(將所有內容保留在屏幕上,避免打破布局等) )
  • 測試在Firefox 3和Internet Explorer 6

代碼: (純香草的JavaScript)

function FitToContent(id, maxHeight) 
{ 
    var text = id && id.style ? id : document.getElementById(id); 
    if (!text) 
     return; 

    /* Accounts for rows being deleted, pixel value may need adjusting */ 
    if (text.clientHeight == text.scrollHeight) { 
     text.style.height = "30px"; 
    } 

    var adjustedHeight = text.clientHeight; 
    if (!maxHeight || maxHeight > adjustedHeight) 
    { 
     adjustedHeight = Math.max(text.scrollHeight, adjustedHeight); 
     if (maxHeight) 
     adjustedHeight = Math.min(maxHeight, adjustedHeight); 
     if (adjustedHeight > text.clientHeight) 
     text.style.height = adjustedHeight + "px"; 
    } 
} 

演示: (在我打字到textarea的使用jQuery的,目標現在 - 如果你有安裝Firebug,粘貼兩個樣本到這個頁面上的控制檯和測試)

$("#post-text").keyup(function() 
{ 
    FitToContent(this, document.documentElement.clientHeight) 
}); 
+0

不錯,但是當文本/行從textarea中刪除時它不會「不增長」。 – SMB 2009-01-23 04:04:30

2

只是重溫這個我已經做了一點整理(儘管有人在Prototype/JavaScript上提供了完整的瓶子可以提供改進建議嗎?)。

var TextAreaResize = Class.create(); 
TextAreaResize.prototype = { 
    initialize: function(element, options) { 
    element = $(element); 
    this.element = element; 

    this.options = Object.extend(
     {}, 
     options || {}); 

    Event.observe(this.element, 'keyup', 
     this.onKeyUp.bindAsEventListener(this)); 
    this.onKeyUp(); 
    }, 

    onKeyUp: function() { 
    // We need this variable because "this" changes in the scope of the 
    // function below. 
    var cols = this.element.cols; 

    var linecount = 0; 
    $A(this.element.value.split("\n")).each(function(l) { 
     // We take long lines into account via the cols divide. 
     linecount += 1 + Math.floor(l.length/cols); 
    }) 

    this.element.rows = linecount; 
    } 
} 

只要將它與調用:

new TextAreaResize('textarea_id_name_here'); 
0

我不需要此功能爲我自己,但沒有從這裏的人的工作作爲我需要他們。

所以我用Orion的代碼並改變了它。

我在最小高度添加了,所以在破壞時它不會變得太小。

function resizeIt(id, maxHeight, minHeight) { 
    var text = id && id.style ? id : document.getElementById(id); 
    var str = text.value; 
    var cols = text.cols; 
    var linecount = 0; 
    var arStr = str.split("\n"); 
    $(arStr).each(function(s) { 
     linecount = linecount + 1 + Math.floor(arStr[s].length/cols); // take into account long lines 
    }); 
    linecount++; 
    linecount = Math.max(minHeight, linecount); 
    linecount = Math.min(maxHeight, linecount); 
    text.rows = linecount; 
}; 
7

這裏有一個原型版本調整文本區域是不依賴於textarea的列數的。這是一種優越的技術,因爲它允許您通過CSS控制文本區域以及具有可變寬度的textarea。此外,此版本還顯示剩餘字符的數量。雖然沒有要求,但它是一個非常有用的功能,如果不需要,很容易刪除。

//inspired by: http://github.com/jaz303/jquery-grab-bag/blob/63d7e445b09698272b2923cb081878fd145b5e3d/javascripts/jquery.autogrow-textarea.js 
if (window.Widget == undefined) window.Widget = {}; 

Widget.Textarea = Class.create({ 
    initialize: function(textarea, options) 
    { 
    this.textarea = $(textarea); 
    this.options = $H({ 
     'min_height' : 30, 
     'max_length' : 400 
    }).update(options); 

    this.textarea.observe('keyup', this.refresh.bind(this)); 

    this._shadow = new Element('div').setStyle({ 
     lineHeight : this.textarea.getStyle('lineHeight'), 
     fontSize : this.textarea.getStyle('fontSize'), 
     fontFamily : this.textarea.getStyle('fontFamily'), 
     position : 'absolute', 
     top: '-10000px', 
     left: '-10000px', 
     width: this.textarea.getWidth() + 'px' 
    }); 
    this.textarea.insert({ after: this._shadow }); 

    this._remainingCharacters = new Element('p').addClassName('remainingCharacters'); 
    this.textarea.insert({after: this._remainingCharacters}); 
    this.refresh(); 
    }, 

    refresh: function() 
    { 
    this._shadow.update($F(this.textarea).replace(/\n/g, '<br/>')); 
    this.textarea.setStyle({ 
     height: Math.max(parseInt(this._shadow.getHeight()) + parseInt(this.textarea.getStyle('lineHeight').replace('px', '')), this.options.get('min_height')) + 'px' 
    }); 

    var remaining = this.options.get('max_length') - $F(this.textarea).length; 
    this._remainingCharacters.update(Math.abs(remaining) + ' characters ' + (remaining > 0 ? 'remaining' : 'over the limit')); 
    } 
}); 

通過致電new Widget.Textarea('element_id')創建窗口小部件。默認選項可以通過將它們作爲對象傳遞來覆蓋。 new Widget.Textarea('element_id', { max_length: 600, min_height: 50})。如果你想創建它的網頁上的所有文字區域,這樣做:

Event.observe(window, 'load', function() { 
    $$('textarea').each(function(textarea) { 
    new Widget.Textarea(textarea); 
    }); 
}); 
0

這裏是一個擴展的原型部件傑里米張貼在6月4日:

它停止用戶進入更字符,如果你在textareas中使用限制。它檢查是否還有字符。如果用戶將文本複製到textarea中,文本將在最大值處截斷。長度:

/** 
* Prototype Widget: Textarea 
* Automatically resizes a textarea and displays the number of remaining chars 
* 
* From: http://stackoverflow.com/questions/7477/autosizing-textarea 
* Inspired by: http://github.com/jaz303/jquery-grab-bag/blob/63d7e445b09698272b2923cb081878fd145b5e3d/javascripts/jquery.autogrow-textarea.js 
*/ 
if (window.Widget == undefined) window.Widget = {}; 

Widget.Textarea = Class.create({ 
    initialize: function(textarea, options){ 
    this.textarea = $(textarea); 
    this.options = $H({ 
     'min_height' : 30, 
     'max_length' : 400 
    }).update(options); 

    this.textarea.observe('keyup', this.refresh.bind(this)); 

    this._shadow = new Element('div').setStyle({ 
     lineHeight : this.textarea.getStyle('lineHeight'), 
     fontSize : this.textarea.getStyle('fontSize'), 
     fontFamily : this.textarea.getStyle('fontFamily'), 
     position : 'absolute', 
     top: '-10000px', 
     left: '-10000px', 
     width: this.textarea.getWidth() + 'px' 
    }); 
    this.textarea.insert({ after: this._shadow }); 

    this._remainingCharacters = new Element('p').addClassName('remainingCharacters'); 
    this.textarea.insert({after: this._remainingCharacters}); 
    this.refresh(); 
    }, 

    refresh: function(){ 
    this._shadow.update($F(this.textarea).replace(/\n/g, '<br/>')); 
    this.textarea.setStyle({ 
     height: Math.max(parseInt(this._shadow.getHeight()) + parseInt(this.textarea.getStyle('lineHeight').replace('px', '')), this.options.get('min_height')) + 'px' 
    }); 

    // Keep the text/character count inside the limits: 
    if($F(this.textarea).length > this.options.get('max_length')){ 
     text = $F(this.textarea).substring(0, this.options.get('max_length')); 
     this.textarea.value = text; 
     return false; 
    } 

    var remaining = this.options.get('max_length') - $F(this.textarea).length; 
    this._remainingCharacters.update(Math.abs(remaining) + ' characters remaining')); 
    } 
}); 
56

對這些答案中的一部分的一種改進是讓CSS做更多的工作。

基本路線似乎是:1)將textarea的內容複製到一個隱藏的div中,2)讓瀏覽器做計算該div高度的工作,然後3)將textarea的高度設置爲該高度。通過讓CSS處理textarea的大小,步驟#3可以省略,代碼量減少。將textarea和hidden div放在同一個容器中,並適當使用visibility:hidden,讓隱藏div的高度直接驅動textarea的高度。

<!doctype> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
<title>Auto-size TextArea Demo</title> 
<script type="text/javascript" src="jquery.js"></script> 
<style> 
#container { 
    position: relative; 
} 

#textArea { 
    box-sizing: border-box; 
    -moz-box-sizing: border-box; 
    -ms-box-sizing: border-box; 
    -webkit-box-sizing: border-box; 
font-family: Helvetica, Arial, sans-serif; 
    height: 100%; 
    overflow: hidden; 
    position: absolute; 
    width: 100%; 
} 

#textCopy { 
    box-sizing: border-box; 
    -moz-box-sizing: border-box; 
    -ms-box-sizing: border-box; 
    -webkit-box-sizing: border-box; 
font-family: Helvetica, Arial, sans-serif; 
    padding: 6px; /* Same border+padding as text area. */ 
padding-bottom: 1.15em; /* A bit more than one additional line of text. */ 
    visibility: hidden; 
    width: 100%; 
} 
</style> 
<script> 
$(function() { 
    $(this.textBox) 
     .change(autoSize) 
     .keydown(autoSize) 
     .keyup(autoSize); 
autoSize(); 
}); 

function autoSize() { 
    // Copy textarea contents; browser will calculate correct height of copy, 
    // which will make overall container taller, which will make textarea taller. 
var text = $("#textArea").val().replace(/\n/g, '<br/>'); 
    $("#textCopy").html(text); 
} 
</script> 
</head> 

<body> 
<div id="container"> 
<textarea id="textArea"></textarea> 
<div id="textCopy"/> 
</div> 
</body> 

</html> 
0

IE瀏覽器,Safari瀏覽器,Chrome和Opera用戶需要記住explicidly設置在CSS的行高值。我做了一個樣式表,它爲所有文本框設置瞭如下的初始屬性。

<style> 
    TEXTAREA { line-height: 14px; font-size: 12px; font-family: arial } 
</style> 
0

這是一個功能我只是在寫jQuery的做到這一點 - 你可以將它移植到Prototype,但他們不支持的jQuery的「活躍度」,因此通過Ajax請求添加不會響應元素。

此版本不僅擴展,而且在按下刪除或退格時也會收縮。

該版本依賴於jQuery 1.4.2。

享受)

http://pastebin.com/SUKeBtnx

用法:

$("#sometextarea").textareacontrol(); 

或(任何jQuery選擇例如)

$("textarea").textareacontrol(); 

據上Internet Explorer 7/Internet Explorer 8,火狐3.5測試和Chrome。一切正常。

4

檢查下面的鏈接: http://james.padolsey.com/javascript/jquery-plugin-autoresize/

$(document).ready(function() { 
    $('.ExpandableTextCSS').autoResize({ 
     // On resize: 
     onResize: function() { 
      $(this).css({ opacity: 0.8 }); 
     }, 
     // After resize: 
     animateCallback: function() { 
      $(this).css({ opacity: 1 }); 
     }, 
     // Quite slow animation: 
     animateDuration: 300, 
     // More extra space: 
     extraSpace:20, 
     //Textarea height limit 
     limit:10 
    }); 
}); 
6

這裏是JQuery一個解決方案:

$(document).ready(function() { 
    var $abc = $("#abc"); 
    $abc.css("height", $abc.attr("scrollHeight")); 
}) 

abcteaxtarea

0

@memical有一個很好的解決方案,用jQuery設置pageload上textarea的高度,但對於我的應用程序,我希望能夠隨着用戶添加更多內容而增加textarea的高度。我內置關閉memical與以下解決方案:

$(document).ready(function() { 
    var $textarea = $("p.body textarea"); 
    $textarea.css("height", ($textarea.attr("scrollHeight") + 20)); 
    $textarea.keyup(function(){ 
     var current_height = $textarea.css("height").replace("px", "")*1; 
     if (current_height + 5 <= $textarea.attr("scrollHeight")) { 
      $textarea.css("height", ($textarea.attr("scrollHeight") + 20)); 
     } 
    }); 
}); 

這不是很順利,但它也不是一個面向客戶的應用程序,所以平滑其實並不重要。 (如果這是面向客戶端,我可能只會使用自動調整大小的jQuery插件。)

1

就像@memical的答案一樣。

但是我發現了一些改進。你可以使用jQuery height()函數。但請注意填充頂部和填充底部像素。否則你的textarea會變得太快。

$(document).ready(function() { 
    $textarea = $("#my-textarea"); 

    // There is some diff between scrollheight and height: 
    // padding-top and padding-bottom 
    var diff = $textarea.prop("scrollHeight") - $textarea.height(); 
    $textarea.live("keyup", function() { 
    var height = $textarea.prop("scrollHeight") - diff; 
    $textarea.height(height); 
    }); 
}); 
2

我做了一件很容易的事。首先,我將TextArea放入DIV中。其次,我已經調用了該腳本的ready函數。

<div id="divTable"> 
    <textarea ID="txt" Rows="1" TextMode="MultiLine" /> 
</div> 

$(document).ready(function() { 
    var heightTextArea = $('#txt').height(); 
    var divTable = document.getElementById('divTable'); 
    $('#txt').attr('rows', parseInt(parseInt(divTable .style.height)/parseInt(altoFila))); 
}); 

簡單。它是渲染後div的最大高度,除以一行的一個TextArea的高度。

0

使用ASP.NET,只是單純地做到這一點:

<html xmlns="http://www.w3.org/1999/xhtml"> 
    <head> 
     <title>Automatic Resize TextBox</title> 
     <script type="text/javascript"> 
      function setHeight(txtarea) { 
       txtarea.style.height = txtdesc.scrollHeight + "px"; 
      } 
     </script> 
    </head> 

    <body> 
     <form id="form1" runat="server"> 
      <asp:TextBox ID="txtarea" runat= "server" TextMode="MultiLine" onkeyup="setHeight(this);" onkeydown="setHeight(this);" /> 
     </form> 
    </body> 
</html> 
0

我的解決方案不使用jQuery(因爲有時他們不必是同一件事)如下。雖然它在Internet Explorer 7只是測試,所以社區可以指出的所有原因,這是錯誤的:

textarea.onkeyup = function() { this.style.height = this.scrollHeight + 'px'; } 

到目前爲止,我真的很喜歡它是如何工作的,我不關心其他的瀏覽器,所以我可能會應用到我所有的文字區域:

// Make all textareas auto-resize vertically 
var textareas = document.getElementsByTagName('textarea'); 

for (i = 0; i<textareas.length; i++) 
{ 
    // Retain textarea's starting height as its minimum height 
    textareas[i].minHeight = textareas[i].offsetHeight; 

    textareas[i].onkeyup = function() { 
     this.style.height = Math.max(this.scrollHeight, this.minHeight) + 'px'; 
    } 
    textareas[i].onkeyup(); // Trigger once to set initial height 
} 
10

可能最短的解決方案:

jQuery(document).ready(function(){ 
    jQuery("#textArea").on("keydown keyup", function(){ 
     this.style.height = "1px"; 
     this.style.height = (this.scrollHeight) + "px"; 
    }); 
}); 

這樣,你不需要任何隱藏層或類似的東西。

注意:根據你如何設計textarea(line-height,padding和類型的東西),你可能需要使用this.style.height = (this.scrollHeight) + "px";

0

對於那些編碼IE並遇到此問題。 IE有一個小竅門,使其100%CSS。

<TEXTAREA style="overflow: visible;" cols="100" ....></TEXTAREA> 

你甚至可以爲IE瀏覽器忽略的rows =「n」提供一個值,但其他瀏覽器會使用它。我真的很討厭實現IE黑客的編碼,但是這個非常有幫助。它可能只適用於怪癖模式。