Ultimate answer
A few days ago, there was a highly adaptive need for textarea. Find a plug-in flexText ,
although not used, but the simplified code is very attractive to me.
it works like this. The structure of HTML is as follows:
<div class="expandingArea">
<span></span><br>
< textarea placeholder= "enter text" > < / textarea >
< / div >
the style of expandingArea is only
.expandingArea{
position:relative;
}
purpose is for absolute positioning of textarea relative to expandingArea:
textarea{
position:absolute;
top:0;
left:0;
height:100%;
}
with this style setting, the height of textArea is always equal to the height of expandingArea, and you only need to adjust the height of
expadingArea to make the height of textarea change. So how do you make the height of expandingArea change with the height of the content? Pre is an important
thing.
pre{
display:block;
visibility:hidden;
}
pre exists in blocks and is invisible, but it takes up space, unlike display:none;, which takes up nothing. At this point, you need to synchronize the content in textarea to the span tag in pre in real time. Because pre does not have postion:absolute
, its height will always affect the height of expandingArea. The summary principle is: pre will change with the height of content, and the height of expandingArea
will change with pre, because the height of textarea
textarea
will change with expandingArea
. As long as you synchronize the content of textarea
to pre, you will achieve the goal of textarea
with content height.
the compatibility of this method is mentioned in the blog of the founder of this method NEIL JENKINS . Personally, I think this method is powerful, did not pass the calculation, logically it is like thinking derivation, the code implementation is not complex, relaxed and happy. In this example, we see another case where a reasonable structure can simplify the code:).
it is true that I have tested a lot of solutions when thinking about this feature. In addition to the two solutions you mentioned, I have also used a solution that I am testing, but if I can improve some glitches, the experience will certainly be better than the current one.
I think of it this way. Since scrollHeight cannot be trusted, we need to look for a trusted height standard. We create another div
so that its css is completely inherited from this textarea, because the height of div can float and scale freely, so we intercept the keyup event of textarea and send its contents to div, and then we define the height of textarea by getting the height of textarea.
before implementing this function, there is another function that needs to be implemented, that is, copying css to another element. Even if there is already a ready-made jQuery solution on the Internet
// csspatch, $(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; iPP)
obj[attr[i]] = jQuery.fn.css2.call(this, attr[i]);
return obj;
};
with these two codes, we can implement
$('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, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/'/g, ''')
.replace(/"/g, '"')
.replace(/ /g, '')
.replace(/(()*)/g, '$1 ')
.replace(/\n/g, '<br />')
.replace(/<br \/>[ ]*$/, '<br />-')
.replace(/<br \/> /g, '<br />');
this.justifyDoc.html(html);
t.height(this.justifyDoc.height());
});
it runs as follows
it has only one problem, that is, there is a little delay in line wrapping, that is, character wrapping first. Then it will be stretched, because we are responding to the keyup
event. Actually, I think the delay is insurmountable, but can you think of a way to make the process less abrupt?
I've been using this code
https://gist.github.com/1192205
it's too complicated to read your answers. My solution: get the number of textarea newline characters, and then update their line height
$('textarea').on('input propertychange', function() {
var v = $(this).val();
var arr = v.split('\n');
var len = arr.length;
$(this).height(len*20);//20;
});
if you want to keep the set number of lines when the number of lines of content is small, you can do this:
$('textarea').on('input propertychange', function() {
var v = $(this).val();
var arr = v.split('\n');
var len = arr.length;
var min=$(this)[0].rows;
if(len>min){
$(this).height(len*20);//20;
}
});
you can add a hidden textArea (similar to the first floor method), take the scrollHeight of this textArea and set it to the input textArea, but here you still have to deal with some compatibility issues after taking the value. With regard to the keyup event, it is best to replace it with the oninput event and the onpropertychange event, so that you can deal with the problem of adding or deleting text with the mouse, but it seems that deleting text using the backspace key under ie9 will not trigger the onpropertychange event.
means that when you enter, adding a line height should not cause the scroll bar to flicker.
/** fake code **/
textarea.keydown = function(e){
if e.keycode == 13 { // key code 13
textarea.height = textarea.height + 1em;
}
}
try
/** fake code **/
textarea.keydown = function(e){
if e.keycode == 13 { // key code 13
textarea.height = textarea.height + 1em;
}
}
http://www.jacklmoore.com/autosize/
This plugin can perfectly solve the problems you have encountered
my idea is to use a div to get the content of the textarea in real time, because the div height varies according to the content. We can get the height of div, and then set the height of div to textarea.
< hr class= answer > h
hh
h
h
hh
h
hh
h
not below, you ask me ~
<textarea class="form-control" style="padding: 0; margin: 0;box-sizing: content-box;" oninput="this.style.height = this.scrollHeight+'px'"> ~~~</textarea>
jq implements textarea highly adaptive . If you don't want to escape the scroll bar, you can overflow and hide
, but the height will not shrink back
when deleted.