div模拟文本框

本文介绍了如何使用HTML的contenteditable属性来模拟textarea文本框,并实现高度自适应。通过监听DOMSubtreeModified事件来处理内容变化,同时解决在移动端聚焦问题,确保光标位置正确。

最近做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属性 :(参考https://w3c.github.io/editing/contentEditable.html#contenteditable

它主要的属性值有:

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));
        }
    }

其实这里面还有很多坑,比如粘贴复制等等。前端就是这样,有时候很小的功能点,里面细节的东西还是挺多的。每每遇到这样的情况,那真是痛并快乐着。哈哈哈。。。

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值