转自:http://www.xuanfengge.com/textarea-on-how-to-achieve-a-high-degree-of-adaptive.html
今天需要些一个回复评论的页面,设计师给的初始界面就是一个只有一行的框。然后当时就想这个交互该怎么实现比较好,然后想起了新浪微博的做法:点击评论,默认显示一行,当输入的文字超过一行或者输入Enter时,输入框的高度会随着改变,直到输入完毕。顿时觉得这个细节做得挺不错的,可以效仿下。下面分享2种实现textarea高度自适应的做法,一种是用div来模拟textarea来实现的,用CSS控制样式,不用JS;另一种是利用JS控制的(因为存在浏览器兼容问题,所以写起来比较麻烦);
demo演示地址:http://www.xuanfengge.com/demo/201308/textarea/demo1.html
因为textarea不支持自适应高度,就是定好高度或者是行数之后,超出部分就会显示滚动条,看起来不美观。
而用DIV来模拟时,首先遇到的问题是:div怎么实现输入功能?
可能我们还是第一次见到这个属性contenteditable,如一个普通的block元素上加个contenteditable="true"
就实现编辑,出现光标了。如
1
|
<
div
contenteditable
=
"true"
>
<
/
div
>
|
contenteditable属性虽是HTML5里面的内容,但是IE似乎老早就支持此标签属性了。所以,兼容性方面还是不用太担心的。
CSS代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
.
textarea
{
width
:
400px
;
min
-
height
:
20px
;
max
-
height
:
300px
;
_height
:
120px
;
margin
-
left
:
auto
;
margin
-
right
:
auto
;
padding
:
3px
;
outline
:
0
;
border
:
1px
solid
#a0b3d6;
font
-
size
:
12px
;
line
-
height
:
24px
;
padding
:
2px
;
word
-
wrap
:
break
-
word
;
overflow
-
x
:
hidden
;
overflow
-
y
:
auto
;
border
-
color
:
rgba
(
82
,
168
,
236
,
0.8
)
;
box
-
shadow
:
inset
0
1px
3px
rgba
(
0
,
0
,
0
,
0.1
)
,
0
0
8px
rgba
(
82
,
168
,
236
,
0.6
)
;
}
|
HTML代码
1
|
<
div
class
=
"textarea"
contenteditable
=
"true"
>
<
br
/
>
<
/
div
>
|
CSS代码中,因为IE6不支持min/max,所以做了hack,其他的也好理解。
demo演示地址:http://www.xuanfengge.com/demo/201308/textarea/demo2.html
这个写法是用原生JS写的,考虑了很多兼容性问题,完全和新浪微博的回复效果一样的功能。有兴趣的童鞋可以仔细分析下代码。
CSS代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#textarea {
display
:
block
;
margin
:
0
auto
;
overflow
:
hidden
;
width
:
550px
;
font
-
size
:
14px
;
height
:
18px
;
line
-
height
:
24px
;
padding
:
2px
;
}
textarea
{
outline
:
0
none
;
border
-
color
:
rgba
(
82
,
168
,
236
,
0.8
)
;
box
-
shadow
:
inset
0
1px
3px
rgba
(
0
,
0
,
0
,
0.1
)
,
0
0
8px
rgba
(
82
,
168
,
236
,
0.6
)
;
}
|
javascript代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
/**
* 文本框根据输入内容自适应高度
* @param {HTMLElement} 输入框元素
* @param {Number} 设置光标与输入框保持的距离(默认0)
* @param {Number} 设置最大高度(可选)
*/
var
autoTextarea
=
function
(
elem
,
extra
,
maxHeight
)
{
extra
=
extra
||
0
;
var
isFirefox
=
!
!
document
.
getBoxObjectFor
||
'mozInnerScreenX'
in
window
,
isOpera
=
!
!
window
.
opera
&&
!
!
window
.
opera
.
toString
(
)
.
indexOf
(
'Opera'
)
,
addEvent
=
function
(
type
,
callback
)
{
elem
.
addEventListener
?
elem
.
addEventListener
(
type
,
callback
,
false
)
:
elem
.
attachEvent
(
'on'
+
type
,
callback
)
;
}
,
getStyle
=
elem
.
currentStyle
?
function
(
name
)
{
var
val
=
elem
.
currentStyle
[
name
]
;
if
(
name
===
'height'
&&
val
.
search
(
/
px
/
i
)
!==
1
)
{
var
rect
=
elem
.
getBoundingClientRect
(
)
;
return
rect
.
bottom
-
rect
.
top
-
parseFloat
(
getStyle
(
'paddingTop'
)
)
-
parseFloat
(
getStyle
(
'paddingBottom'
)
)
+
'px'
;
}
;
return
val
;
}
:
function
(
name
)
{
return
getComputedStyle
(
elem
,
null
)
[
name
]
;
}
,
minHeight
=
parseFloat
(
getStyle
(
'height'
)
)
;
elem
.
style
.
resize
=
'none'
;
var
change
=
function
(
)
{
var
scrollTop
,
height
,
padding
=
0
,
style
=
elem
.
style
;
if
(
elem
.
_length
===
elem
.
value
.
length
)
return
;
elem
.
_length
=
elem
.
value
.
length
;
if
(
!
isFirefox
&&
!
isOpera
)
{
padding
=
parseInt
(
getStyle
(
'paddingTop'
)
)
+
parseInt
(
getStyle
(
'paddingBottom'
)
)
;
}
;
scrollTop
=
document
.
body
.
scrollTop
||
document
.
documentElement
.
scrollTop
;
elem
.
style
.
height
=
minHeight
+
'px'
;
if
(
elem
.
scrollHeight
>
minHeight
)
{
if
(
maxHeight
&&
elem
.
scrollHeight
>
maxHeight
)
{
height
=
maxHeight
-
padding
;
style
.
overflowY
=
'auto'
;
}
else
{
height
=
elem
.
scrollHeight
-
padding
;
style
.
overflowY
=
'hidden'
;
}
;
style
.
height
=
height
+
extra
+
'px'
;
scrollTop
+=
parseInt
(
style
.
height
)
-
elem
.
currHeight
;
document
.
body
.
scrollTop
=
scrollTop
;
document
.
documentElement
.
scrollTop
=
scrollTop
;
elem
.
currHeight
=
parseInt
(
style
.
height
)
;
}
;
}
;
addEvent
(
'propertychange'
,
change
)
;
addEvent
(
'input'
,
change
)
;
addEvent
(
'focus'
,
change
)
;
change
(
)
;
}
;
|
HTML代码(写在body里面的)
1
2
3
4
5
|
<
textarea
id
=
"textarea"
placeholder
=
"回复内容"
>
<
/
textarea
>
var
text
=
document
.
getElementById
(
"textarea"
)
;
autoTextarea
(
text
)
;
// 调用
|