最近做H5页面,经常碰见实现高度自适应且计数的文本框需求,所以在这里记录一下。
其实很早之前就看了张鑫旭的“div模拟textarea文本域轻松实现高度自适应”,现在的做法也就是文章中提到的方法,主要是用到contenteditable属性。
html结构如下:
<div class="textarea_wrap">
<div id="textarea" class="textarea" name="" contenteditable="plaintext-only"></div>
<span class="textnum font9"><em id="textnum">0</em>/30</span>
</div>
它主要的属性值有:
contenteditable="inherit"
contenteditable=""
contenteditable="events"
contenteditable="caret"
contenteditable="typing"
contenteditable="plaintext-only"
contenteditable="true"
contenteditable="false"
其实在模拟文本框时,常用的就是"plaintext-only"、"true","plaintext-only"可以实现可以让编辑区域只能键入纯文本
其实css中有一个属性(user-modify)也能实现让元素内只能输入纯文本,但是由于目前好像只有webkit内核支持(-webkit-),所以效果没上面好。
下面的css中有写:(针对H5,对pc的兼容性没有考虑,如有需要可参考http://www.zhangxinxu.com/wordpress/2010/12/div-textarea-height-auto/)
.textarea_wrap{
position: relative;
height: 2rem;
padding: 0 0.75rem;
font-size: 0.7rem;
color: #a3a3a3;
background-color: #f7f7f7;
border-top: 1px solid #ececec;
border-bottom: 1px solid #ececec;
}
.textarea{
display: inline-block;
min-height: 1rem;
max-height: 6.8rem;
width: 78%;
outline: 0;
color: #333;
word-wrap: break-word;
overflow-y: scroll;
margin-left: 0.75rem;
/* user-modify: read-write-plaintext-only;
-webkit-user-modify: read-write-plaintext-only;*//*只有webkit内核支持*/
}
.textnum{
position: absolute;
right: 4%;
bottom: 0.25rem;
position: absolute;
font-size: 0.45rem;
em{
font-style: normal;
&.flow{
color: #f77171;
}
}
}
/* font-size:9px chrome*/
.font9{
font-size: 0.45rem;
}
@media screen and (max-width:320px){
.font9{
font-size: 0.45rem;
-webkit-transform: scale(0.75);
-o-transform: scale(1);
}
}
首先,主要介绍一下DOMSubtreeModified事件。(参考http://www.cnblogs.com/zzsdream/p/5085619.html)
DOMSubtreeModified:在DOM结构中发生的任何变化时触发。这个事件在其他任何事件触发后都会触发。
之所以使用这个属性,是因为div上木有change事件,当手机上弹出软键盘是,采用keyup、keydown也会有问题,DOMSubtreeModified事件完美的解决的这些问题。
其次,说一下聚焦问题。当文字超出最大限制时,再次输入,光标可能出现在div内容头部,这不是我们希望的,于是用set_focus()解决。
函数里面的内容就不细说了,想要进一步了解,可自行搜索。
$("body").on('DOMSubtreeModified', '#textarea', function() {
changeLength('#textarea', '#textnum', 30, 20);
});
function set_focus(el) {//聚焦在文本后面
el = el[0]; //jquery 对象转dom对象
el.focus();
if ($.browser.msie) {
var range = document.selection.createRange();
this.last = range;
range.moveToElementText(el);
range.select();
document.selection.empty(); //取消选中
} else {
var range = document.createRange();
range.selectNodeContents(el);
range.collapse(false);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
}
function changeLength(textObj, numObj, maxLen, limitLen) {//计数
var txtval = $.trim($(textObj).text()),
txtlen = txtval.length;
$(numObj).text(txtlen);
if (txtlen > 0) {
$(textObj).next('.textarea_tips').css('display', 'none');
} else {
$(textObj).next('.textarea_tips').css('display', 'block');
}
if (txtlen > limitLen-1) {
$(numObj).addClass('colred');
} else {
$(numObj).removeClass('colred');
}
if (txtlen >= maxLen) {
$(textObj).text(txtval.substring(0, maxLen - 1));
$(numObj).html(txtlen);
set_focus($(textObj));
}
}
其实这里面还有很多坑,比如粘贴复制等等。前端就是这样,有时候很小的功能点,里面细节的东西还是挺多的。每每遇到这样的情况,那真是痛并快乐着。哈哈哈。。。
本文介绍了如何使用HTML的contenteditable属性来模拟textarea文本框,并实现高度自适应。通过监听DOMSubtreeModified事件来处理内容变化,同时解决在移动端聚焦问题,确保光标位置正确。
898

被折叠的 条评论
为什么被折叠?



