Prototype을 사용하여 텍스트 영역의 크기를 자동으로 조정하는 방법은 무엇입니까?
-
08-06-2019 - |
문제
저는 현재 제가 일하는 회사의 내부 판매 신청서를 작성하고 있는데, 사용자가 배송 주소를 변경할 수 있는 양식을 가지고 있습니다.
이제 기본 주소 세부 정보에 사용하는 텍스트 영역이 텍스트 영역만 차지하고 텍스트가 변경되면 자동으로 크기가 조정된다면 훨씬 더 멋져 보일 것이라고 생각합니다.
현재 스크린샷은 다음과 같습니다.
어떤 아이디어가 있나요?
@크리스
좋은 지적이지만 크기를 조정하고 싶은 이유가 있습니다.나는 그것이 차지하는 영역이 그 안에 포함된 정보의 영역이기를 원합니다.스크린샷에서 볼 수 있듯이 고정된 텍스트 영역이 있으면 수직 공간이 꽤 많이 차지합니다.
글꼴을 줄일 수 있지만 크고 읽기 쉬운 주소가 필요합니다.이제 텍스트 영역의 크기를 줄일 수 있지만 주소 줄이 3~4줄(1줄은 5줄)인 사람들에게는 문제가 있습니다.사용자가 스크롤바를 사용하도록 하는 것은 절대 금물입니다.
좀 더 구체적으로 말씀드려야 할 것 같습니다.세로 크기를 조정한 후 너비가 그다지 중요하지 않습니다.여기서 발생하는 유일한 문제는 창 너비가 너무 작을 때(스크린샷에서 볼 수 있듯이) ISO 번호(큰 "1")가 주소 아래로 밀려나는 것입니다.
속임수를 쓰는 것이 아닙니다.불필요한 공간을 차지하지 않고 그 안의 모든 텍스트를 표시하는 사용자가 편집할 수 있는 텍스트 필드를 갖는 것입니다.
누군가가 문제에 접근하는 다른 방법을 생각해낸다면 나도 그것에 대해 열려 있습니다.
코드가 좀 이상해서 조금 수정했습니다.방금 입력한 문자를 고려하지 않기 때문에 키업 시 활성화되도록 변경했습니다.
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;
};
해결책
Facebook에서는 사람들의 담벼락에 글을 쓸 때 이를 수행하지만 크기는 수직으로만 조정됩니다.
가로 크기 조정은 단어 줄 바꿈, 긴 줄 등으로 인해 혼란스러워 보이지만 세로 크기 조정은 꽤 안전하고 좋은 것 같습니다.
내가 아는 페이스북 초보자 중 누구도 이에 대해 언급하거나 혼란스러워한 적이 없습니다.나는 이것을 '계속해서 구현하라'고 말하는 일화적인 증거로 사용하고 싶습니다.
이를 수행하는 일부 JavaScript 코드는 다음을 사용합니다. 원기 (왜냐하면 내가 아는 내용이니까):
<!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>
추신:분명히 이 JavaScript 코드는 매우 순진하고 잘 테스트되지 않았으므로 소설이 들어 있는 텍스트 상자에 사용하고 싶지 않을 수도 있지만 일반적인 아이디어는 얻을 수 있습니다.
다른 팁
이러한 답변 중 일부를 개선한 것 중 하나는 CSS가 더 많은 작업을 수행하도록 하는 것입니다.
기본 경로는 다음과 같습니다.
- 컨테이너 요소를 생성하여
textarea
그리고 숨겨진div
- Javascript를 사용하여
textarea
의 콘텐츠가div
'에스 - 브라우저가 해당 div의 높이를 계산하도록 하세요.
- 브라우저가 숨겨진 렌더링/크기 조정을 처리하기 때문에
div
, 우리는 명시 적으로 설정하지 않습니다textarea
의 키.
document.addEventListener('DOMContentLoaded', () => {
textArea.addEventListener('change', autosize, false)
textArea.addEventListener('keydown', autosize, false)
textArea.addEventListener('keyup', autosize, false)
autosize()
}, false)
function autosize() {
// Copy textarea contents to div browser will calculate correct height
// of copy, which will make overall container taller, which will make
// textarea taller.
textCopy.innerHTML = textArea.value.replace(/\n/g, '<br/>')
}
html, body, textarea {
font-family: sans-serif;
font-size: 14px;
}
.textarea-container {
position: relative;
}
.textarea-container > div, .textarea-container > textarea {
word-wrap: break-word; /* make sure the div and the textarea wrap words in the same way */
box-sizing: border-box;
padding: 2px;
width: 100%;
}
.textarea-container > textarea {
overflow: hidden;
position: absolute;
height: 100%;
}
.textarea-container > div {
padding-bottom: 1.5em; /* A bit more than one additional line of text. */
visibility: hidden;
width: 100%;
}
<div class="textarea-container">
<textarea id="textArea"></textarea>
<div id="textCopy"></div>
</div>
텍스트 영역의 크기를 자동으로 조정하는 또 다른 기술은 다음과 같습니다.
- 줄 높이 대신 픽셀 높이를 사용합니다.비례 글꼴을 사용하는 경우 줄 바꿈을 더 정확하게 처리할 수 있습니다.
- ID 또는 요소를 입력으로 허용합니다.
- 선택적 최대 높이 매개변수를 허용합니다. 텍스트 영역이 특정 크기를 초과하지 않도록 하려는 경우에 유용합니다(모든 내용을 화면에 표시하고 레이아웃이 깨지지 않도록 하는 등).
- Firefox 3에서 테스트되었으며 인터넷 익스플로러 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";
}
}
데모:(jQuery를 사용하여 지금 내가 입력하고 있는 텍스트 영역을 대상으로 합니다. 개똥 벌레 설치한 후 두 샘플을 모두 콘솔에 붙여넣고 이 페이지에서 테스트하세요)
$("#post-text").keyup(function()
{
FitToContent(this, document.documentElement.clientHeight)
});
아마도 가장 짧은 해결책은 다음과 같습니다.
jQuery(document).ready(function(){
jQuery("#textArea").on("keydown keyup", function(){
this.style.height = "1px";
this.style.height = (this.scrollHeight) + "px";
});
});
이렇게 하면 숨겨진 div나 이와 유사한 것이 필요하지 않습니다.
메모:너랑 놀아야 할 수도 있어 this.style.height = (this.scrollHeight) + "px";
텍스트 영역의 스타일을 지정하는 방법(줄 높이, 패딩 등)에 따라 다릅니다.
여기 원기 텍스트 영역의 열 수에 의존하지 않는 텍스트 영역 크기 조정 버전.이는 CSS를 통해 텍스트 영역을 제어할 수 있을 뿐만 아니라 가변 너비 텍스트 영역을 가질 수 있기 때문에 뛰어난 기술입니다.또한 이 버전에서는 남은 문자 수가 표시됩니다.요청되지는 않았지만 매우 유용한 기능이며 원치 않는 경우 쉽게 제거할 수 있습니다.
//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);
});
});
여기에 해결책이 있습니다. JQuery
:
$(document).ready(function() {
var $abc = $("#abc");
$abc.css("height", $abc.attr("scrollHeight"));
})
abc
는 teaxtarea
.
아래 링크를 확인하세요: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
});
});
이것을 다시 살펴보니 조금 더 깔끔하게 만들었습니다(물병을 가득 채운 사람은 원기/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');
나는 아주 쉬운 것을 만들었습니다.먼저 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 높이로 나눈 값입니다.
나 자신을 위해 이 기능이 필요했지만 여기에 있는 기능 중 어느 것도 내가 필요로 하는 대로 작동하지 않았습니다.
그래서 오리온의 코드를 사용해서 바꿔봤습니다.
파괴할 때 너무 작아지지 않도록 최소 높이를 추가했습니다.
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;
};
@memical의 답변처럼요.
그러나 몇 가지 개선 사항을 찾았습니다.jQuery를 사용할 수 있습니다 height()
기능.그러나 패딩 상단 및 패딩 하단 픽셀에 유의하세요.그렇지 않으면 텍스트 영역이 너무 빨리 커질 것입니다.
$(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);
});
});
jQuery를 사용하지 않는 내 솔루션(때로는 동일할 필요가 없기 때문에)은 다음과 같습니다.에서만 테스트되었지만 인터넷 익스플로러 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
}
다음은 Jeremy가 6월 4일에 게시한 Prototype 위젯의 확장입니다.
텍스트 영역에서 제한을 사용하는 경우 사용자가 더 많은 문자를 입력하는 것을 중지합니다.남은 문자가 있는지 확인합니다.사용자가 텍스트를 텍스트 영역에 복사하면 텍스트가 최대로 잘립니다.길이:
/**
* 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'));
}
});
@memical jQuery를 사용하여 페이지 로드 시 텍스트 영역의 높이를 설정하는 멋진 솔루션이 있었지만 내 애플리케이션에서는 사용자가 더 많은 콘텐츠를 추가함에 따라 텍스트 영역의 높이를 늘릴 수 있기를 원했습니다.나는 다음을 사용하여 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 플러그인을 사용했을 것입니다.)
IE용으로 코딩하고 이 문제에 직면한 사람들을 위한 것입니다.IE에는 100% CSS로 만드는 약간의 트릭이 있습니다.
<TEXTAREA style="overflow: visible;" cols="100" ....></TEXTAREA>
IE에서는 무시하지만 다른 브라우저에서는 사용하게 될rows="n" 값을 제공할 수도 있습니다.나는 IE 핵을 구현하는 코딩을 정말 싫어하지만 이것은 매우 도움이 됩니다.Quirks 모드에서만 작동할 수도 있습니다.
인터넷 익스플로러, 사파리, 크롬 및 오페라 사용자는 CSS에서 line-height 값을 명시적으로 설정해야 합니다.다음과 같이 모든 텍스트 상자의 초기 속성을 설정하는 스타일시트를 작성합니다.
<style>
TEXTAREA { line-height: 14px; font-size: 12px; font-family: arial }
</style>
여기에 제가 방금 jQuery로 작성한 함수가 있습니다. 이를 다음으로 포팅할 수 있습니다. 원기, 그러나 jQuery의 "활성"을 지원하지 않으므로 Ajax 요청으로 추가된 요소는 응답하지 않습니다.
이 버전은 확장될 뿐만 아니라 삭제 또는 백스페이스를 누르면 축소됩니다.
이 버전은 jQuery 1.4.2를 사용합니다.
즐기다 ;)
용법:
$("#sometextarea").textareacontrol();
또는 (예를 들어 jQuery 선택기)
$("textarea").textareacontrol();
그것은 테스트되었습니다 인터넷 익스플로러 7/인터넷 익스플로러 8, Firefox 3.5 및 Chrome.모두 잘 작동합니다.
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>